UNPKG

12.5 kBJavaScriptView Raw
1System.register(['react', 'jotai'], (function (exports) {
2 'use strict';
3 var useRef, useEffect, useContext, useState, useCallback, useAtom, SECRET_INTERNAL_getScopeContext;
4 return {
5 setters: [function (module) {
6 useRef = module.useRef;
7 useEffect = module.useEffect;
8 useContext = module.useContext;
9 useState = module.useState;
10 useCallback = module.useCallback;
11 }, function (module) {
12 useAtom = module.useAtom;
13 SECRET_INTERNAL_getScopeContext = module.SECRET_INTERNAL_getScopeContext;
14 }],
15 execute: (function () {
16
17 exports({
18 useAtomDevtools: useAtomDevtools,
19 useAtomsDevtools: useAtomsDevtools,
20 useAtomsSnapshot: useAtomsSnapshot,
21 useGotoAtomsSnapshot: useGotoAtomsSnapshot
22 });
23
24 function useAtomDevtools(anAtom, options, deprecatedScope) {
25 if (typeof options === "string" || typeof deprecatedScope !== "undefined") {
26 console.warn("DEPRECATED [useAtomDevtools] use DevtoolOptions");
27 options = {
28 name: options,
29 scope: deprecatedScope
30 };
31 }
32 const { enabled, name, scope } = options || {};
33 let extension;
34 try {
35 extension = (enabled != null ? enabled : true) && window.__REDUX_DEVTOOLS_EXTENSION__;
36 } catch {
37 }
38 if (!extension) {
39 if (enabled) {
40 console.warn("Please install/enable Redux devtools extension");
41 }
42 }
43 const [value, setValue] = useAtom(anAtom, scope);
44 const lastValue = useRef(value);
45 const isTimeTraveling = useRef(false);
46 const devtools = useRef();
47 const atomName = name || anAtom.debugLabel || anAtom.toString();
48 useEffect(() => {
49 if (!extension) {
50 return;
51 }
52 const setValueIfWritable = (value2) => {
53 if (typeof setValue === "function") {
54 setValue(value2);
55 return;
56 }
57 console.warn("[Warn] you cannot do write operations (Time-travelling, etc) in read-only atoms\n", anAtom);
58 };
59 devtools.current = extension.connect({ name: atomName });
60 const unsubscribe = devtools.current.subscribe((message) => {
61 var _a, _b, _c, _d, _e, _f;
62 if (message.type === "ACTION" && message.payload) {
63 try {
64 setValueIfWritable(JSON.parse(message.payload));
65 } catch (e) {
66 console.error("please dispatch a serializable value that JSON.parse() support\n", e);
67 }
68 } else if (message.type === "DISPATCH" && message.state) {
69 if (((_a = message.payload) == null ? void 0 : _a.type) === "JUMP_TO_ACTION" || ((_b = message.payload) == null ? void 0 : _b.type) === "JUMP_TO_STATE") {
70 isTimeTraveling.current = true;
71 setValueIfWritable(JSON.parse(message.state));
72 }
73 } else if (message.type === "DISPATCH" && ((_c = message.payload) == null ? void 0 : _c.type) === "COMMIT") {
74 (_d = devtools.current) == null ? void 0 : _d.init(lastValue.current);
75 } else if (message.type === "DISPATCH" && ((_e = message.payload) == null ? void 0 : _e.type) === "IMPORT_STATE") {
76 const computedStates = ((_f = message.payload.nextLiftedState) == null ? void 0 : _f.computedStates) || [];
77 computedStates.forEach(({ state }, index) => {
78 var _a2;
79 if (index === 0) {
80 (_a2 = devtools.current) == null ? void 0 : _a2.init(state);
81 } else {
82 setValueIfWritable(state);
83 }
84 });
85 }
86 });
87 devtools.current.shouldInit = true;
88 return unsubscribe;
89 }, [anAtom, extension, atomName, setValue]);
90 useEffect(() => {
91 if (!devtools.current) {
92 return;
93 }
94 lastValue.current = value;
95 if (devtools.current.shouldInit) {
96 devtools.current.init(value);
97 devtools.current.shouldInit = false;
98 } else if (isTimeTraveling.current) {
99 isTimeTraveling.current = false;
100 } else {
101 devtools.current.send(`${atomName} - ${new Date().toLocaleString()}`, value);
102 }
103 }, [anAtom, extension, atomName, value]);
104 }
105
106 const RESTORE_ATOMS = "h";
107 const DEV_SUBSCRIBE_STATE = "n";
108 const DEV_GET_MOUNTED_ATOMS = "l";
109 const DEV_GET_ATOM_STATE = "a";
110 const DEV_GET_MOUNTED = "m";
111
112 const createAtomsSnapshot = (store, atoms) => {
113 const tuples = atoms.map((atom) => {
114 var _a, _b;
115 const atomState = (_b = (_a = store[DEV_GET_ATOM_STATE]) == null ? void 0 : _a.call(store, atom)) != null ? _b : {};
116 return [atom, "v" in atomState ? atomState.v : void 0];
117 });
118 return new Map(tuples);
119 };
120 function useAtomsSnapshot(scope) {
121 const ScopeContext = SECRET_INTERNAL_getScopeContext(scope);
122 const scopeContainer = useContext(ScopeContext);
123 const store = scopeContainer.s;
124 if (!store[DEV_SUBSCRIBE_STATE]) {
125 throw new Error("useAtomsSnapshot can only be used in dev mode.");
126 }
127 const [atomsSnapshot, setAtomsSnapshot] = useState(() => /* @__PURE__ */ new Map());
128 useEffect(() => {
129 var _a;
130 const callback = () => {
131 var _a2;
132 const atoms = Array.from(((_a2 = store[DEV_GET_MOUNTED_ATOMS]) == null ? void 0 : _a2.call(store)) || []);
133 setAtomsSnapshot(createAtomsSnapshot(store, atoms));
134 };
135 const unsubscribe = (_a = store[DEV_SUBSCRIBE_STATE]) == null ? void 0 : _a.call(store, callback);
136 callback();
137 return unsubscribe;
138 }, [store]);
139 return atomsSnapshot;
140 }
141
142 function useGotoAtomsSnapshot(scope) {
143 const ScopeContext = SECRET_INTERNAL_getScopeContext(scope);
144 const scopeContainer = useContext(ScopeContext);
145 const store = scopeContainer.s;
146 if (!store[DEV_SUBSCRIBE_STATE]) {
147 throw new Error("useGotoAtomsSnapshot can only be used in dev mode.");
148 }
149 return useCallback((values) => {
150 store[RESTORE_ATOMS](values);
151 }, [store]);
152 }
153
154 const isEqualAtomsValues = (left, right) => left.size === right.size && Array.from(left).every(([left2, v]) => Object.is(right.get(left2), v));
155 const isEqualAtomsDependents = (left, right) => left.size === right.size && Array.from(left).every(([a, dLeft]) => {
156 const dRight = right.get(a);
157 return dRight && dLeft.size === dRight.size && Array.from(dLeft).every((d) => dRight.has(d));
158 });
159 const atomToPrintable = (atom) => atom.debugLabel ? `${atom}:${atom.debugLabel}` : `${atom}`;
160 const getDevtoolsState = (atomsSnapshot) => {
161 const values = {};
162 atomsSnapshot[0].forEach((v, atom) => {
163 values[atomToPrintable(atom)] = v;
164 });
165 const dependents = {};
166 atomsSnapshot[1].forEach((d, atom) => {
167 dependents[atomToPrintable(atom)] = Array.from(d).map(atomToPrintable);
168 });
169 return {
170 values,
171 dependents
172 };
173 };
174 function useAtomsDevtools(name, options) {
175 if (typeof options !== "undefined" && typeof options !== "object") {
176 console.warn("DEPRECATED [useAtomsDevtools] use DevtoolsOptions");
177 options = { scope: options };
178 }
179 const { enabled, scope } = options || {};
180 const ScopeContext = SECRET_INTERNAL_getScopeContext(scope);
181 const { s: store, w: versionedWrite } = useContext(ScopeContext);
182 let extension;
183 try {
184 extension = (enabled != null ? enabled : true) && window.__REDUX_DEVTOOLS_EXTENSION__;
185 } catch {
186 }
187 if (!extension) {
188 if (enabled) {
189 console.warn("Please install/enable Redux devtools extension");
190 }
191 }
192 if (extension && !store[DEV_SUBSCRIBE_STATE]) {
193 throw new Error("useAtomsDevtools can only be used in dev mode.");
194 }
195 const [atomsSnapshot, setAtomsSnapshot] = useState(() => [
196 /* @__PURE__ */ new Map(),
197 /* @__PURE__ */ new Map()
198 ]);
199 useEffect(() => {
200 var _a;
201 if (!extension) {
202 return;
203 }
204 const callback = () => {
205 var _a2, _b, _c;
206 const values = /* @__PURE__ */ new Map();
207 const dependents = /* @__PURE__ */ new Map();
208 for (const atom of ((_a2 = store[DEV_GET_MOUNTED_ATOMS]) == null ? void 0 : _a2.call(store)) || []) {
209 const atomState = (_b = store[DEV_GET_ATOM_STATE]) == null ? void 0 : _b.call(store, atom);
210 if (atomState) {
211 if (atomState.r === atomState.i) {
212 return;
213 }
214 if ("v" in atomState) {
215 values.set(atom, atomState.v);
216 }
217 }
218 const mounted = (_c = store[DEV_GET_MOUNTED]) == null ? void 0 : _c.call(store, atom);
219 if (mounted) {
220 dependents.set(atom, mounted.t);
221 }
222 }
223 setAtomsSnapshot((prev) => {
224 if (isEqualAtomsValues(prev[0], values) && isEqualAtomsDependents(prev[1], dependents)) {
225 return prev;
226 }
227 return [values, dependents];
228 });
229 };
230 const unsubscribe = (_a = store[DEV_SUBSCRIBE_STATE]) == null ? void 0 : _a.call(store, callback);
231 callback();
232 return unsubscribe;
233 }, [extension, store]);
234 const goToSnapshot = useCallback((values) => {
235 if (versionedWrite) {
236 versionedWrite((version) => {
237 store[RESTORE_ATOMS](values, version);
238 });
239 } else {
240 store[RESTORE_ATOMS](values);
241 }
242 }, [store, versionedWrite]);
243 const isTimeTraveling = useRef(false);
244 const isRecording = useRef(true);
245 const devtools = useRef();
246 const snapshots = useRef([]);
247 useEffect(() => {
248 if (!extension) {
249 return;
250 }
251 const getSnapshotAt = (index = snapshots.current.length - 1) => {
252 const snapshot = snapshots.current[index >= 0 ? index : 0];
253 if (!snapshot) {
254 throw new Error("snaphost index out of bounds");
255 }
256 return snapshot;
257 };
258 const connection = extension.connect({ name });
259 const devtoolsUnsubscribe = connection.subscribe((message) => {
260 var _a;
261 switch (message.type) {
262 case "DISPATCH":
263 switch ((_a = message.payload) == null ? void 0 : _a.type) {
264 case "RESET":
265 break;
266 case "COMMIT":
267 connection.init(getDevtoolsState(getSnapshotAt()));
268 snapshots.current = [];
269 break;
270 case "JUMP_TO_ACTION":
271 case "JUMP_TO_STATE":
272 isTimeTraveling.current = true;
273 goToSnapshot(getSnapshotAt(message.payload.actionId - 1)[0]);
274 break;
275 case "PAUSE_RECORDING":
276 isRecording.current = !isRecording.current;
277 break;
278 }
279 }
280 });
281 devtools.current = connection;
282 devtools.current.shouldInit = true;
283 return devtoolsUnsubscribe;
284 }, [extension, goToSnapshot, name]);
285 useEffect(() => {
286 if (!devtools.current) {
287 return;
288 }
289 if (devtools.current.shouldInit) {
290 devtools.current.init(void 0);
291 devtools.current.shouldInit = false;
292 return;
293 }
294 if (isTimeTraveling.current) {
295 isTimeTraveling.current = false;
296 } else if (isRecording.current) {
297 snapshots.current.push(atomsSnapshot);
298 devtools.current.send({
299 type: `${snapshots.current.length}`,
300 updatedAt: new Date().toLocaleString()
301 }, getDevtoolsState(atomsSnapshot));
302 }
303 }, [atomsSnapshot]);
304 }
305
306 })
307 };
308}));