@lucianojd/recoil-sync-next
Version:
recoil-sync stores for Next.js
79 lines (78 loc) • 2.6 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
/*
* A part of these functions are:
* Copyright (c) Facebook, Inc. and its affiliates.
* Released under the MIT license.
* https://github.com/facebookexperimental/Recoil/blob/main/LICENSE
*/
import { useCallback, useMemo } from 'react';
import { DefaultValue } from 'recoil';
import { RecoilSync } from 'recoil-sync';
import transit from 'transit-js';
import { useSyncHistory } from './useSyncHistory';
import { useSyncHistoryNext } from './useSyncHistoryNext';
const BUILTIN_HANDLERS = [
{
tag: 'Date',
class: Date,
write: (x) => x.toISOString(),
read: (str) => new Date(str),
},
{
tag: 'Set',
class: Set,
write: (x) => Array.from(x),
read: (arr) => new Set(arr),
},
{
tag: 'Map',
class: Map,
write: (x) => Array.from(x.entries()),
read: (arr) => new Map(arr),
},
{
tag: '__DV',
class: DefaultValue,
write: () => 0,
read: () => new DefaultValue(),
},
];
export const RecoilHistorySyncTransitNext = ({ storeKey, handlers: optionalHandlers, children, }) => {
const handlers = useMemo(() => [...BUILTIN_HANDLERS, ...(optionalHandlers !== null && optionalHandlers !== void 0 ? optionalHandlers : [])], [optionalHandlers]);
const writer = useMemo(() => transit.writer('json', {
handlers: transit.map(handlers
.map((handler) => [
handler.class,
transit.makeWriteHandler({
tag: () => handler.tag,
rep: handler.write,
stringRep: () => null,
}),
])
.flat(1)),
}), [handlers]);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const serialize = useCallback((x) => writer.write(x), [writer]);
const reader = useMemo(() => transit.reader('json', {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
handlers: handlers.reduce((c, { tag, read }) => {
c[tag] = read;
return c;
}, {}),
mapBuilder: {
init: () => ({}),
add: (ret, key, val) => {
ret[key] = val;
return ret;
},
finalize: (ret) => ret,
},
}), [handlers]);
const deserialize = useCallback((x) => reader.read(x), [reader]);
const opts = useSyncHistory(useSyncHistoryNext({
storeKey,
serialize,
deserialize,
}));
return _jsx(RecoilSync, { ...opts, children: children });
};