UNPKG

15.1 kBJavaScriptView Raw
1'use strict';
2
3var react = require('react');
4var jotai = require('jotai');
5
6function _extends() {
7 _extends = Object.assign ? Object.assign.bind() : function (target) {
8 for (var i = 1; i < arguments.length; i++) {
9 var source = arguments[i];
10 for (var key in source) {
11 if (Object.prototype.hasOwnProperty.call(source, key)) {
12 target[key] = source[key];
13 }
14 }
15 }
16 return target;
17 };
18 return _extends.apply(this, arguments);
19}
20function _unsupportedIterableToArray(o, minLen) {
21 if (!o) return;
22 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
23 var n = Object.prototype.toString.call(o).slice(8, -1);
24 if (n === "Object" && o.constructor) n = o.constructor.name;
25 if (n === "Map" || n === "Set") return Array.from(o);
26 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
27}
28function _arrayLikeToArray(arr, len) {
29 if (len == null || len > arr.length) len = arr.length;
30 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
31 return arr2;
32}
33function _createForOfIteratorHelperLoose(o, allowArrayLike) {
34 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
35 if (it) return (it = it.call(o)).next.bind(it);
36 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
37 if (it) o = it;
38 var i = 0;
39 return function () {
40 if (i >= o.length) return {
41 done: true
42 };
43 return {
44 done: false,
45 value: o[i++]
46 };
47 };
48 }
49 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
50}
51
52var RESTORE_ATOMS = 'h';
53
54var DEV_SUBSCRIBE_STATE = 'n';
55var DEV_GET_MOUNTED_ATOMS = 'l';
56var DEV_GET_ATOM_STATE = 'a';
57var DEV_GET_MOUNTED = 'm';
58
59var atomToPrintable$1 = function atomToPrintable(atom) {
60 return atom.debugLabel || atom.toString();
61};
62var stateToPrintable = function stateToPrintable(_ref) {
63 var store = _ref[0],
64 atoms = _ref[1];
65 return Object.fromEntries(atoms.flatMap(function (atom) {
66 var _store$DEV_GET_MOUNTE, _store$DEV_GET_ATOM_S;
67 var mounted = (_store$DEV_GET_MOUNTE = store[DEV_GET_MOUNTED]) == null ? void 0 : _store$DEV_GET_MOUNTE.call(store, atom);
68 if (!mounted) {
69 return [];
70 }
71 var dependents = mounted.t;
72 var atomState = ((_store$DEV_GET_ATOM_S = store[DEV_GET_ATOM_STATE]) == null ? void 0 : _store$DEV_GET_ATOM_S.call(store, atom)) || {};
73 return [[atomToPrintable$1(atom), _extends({}, 'e' in atomState && {
74 error: atomState.e
75 }, 'p' in atomState && {
76 promise: atomState.p
77 }, 'v' in atomState && {
78 value: atomState.v
79 }, {
80 dependents: Array.from(dependents).map(atomToPrintable$1)
81 })]];
82 }));
83};
84var useAtomsDebugValue = function useAtomsDebugValue(options) {
85 var _options$enabled;
86 var enabled = (_options$enabled = options == null ? void 0 : options.enabled) != null ? _options$enabled : process.env.NODE_ENV !== "production";
87 var ScopeContext = jotai.SECRET_INTERNAL_getScopeContext(options == null ? void 0 : options.scope);
88 var _useContext = react.useContext(ScopeContext),
89 store = _useContext.s;
90 var _useState = react.useState([]),
91 atoms = _useState[0],
92 setAtoms = _useState[1];
93 react.useEffect(function () {
94 var _store$DEV_SUBSCRIBE_;
95 if (!enabled) {
96 return;
97 }
98 var callback = function callback() {
99 var _store$DEV_GET_MOUNTE2;
100 setAtoms(Array.from(((_store$DEV_GET_MOUNTE2 = store[DEV_GET_MOUNTED_ATOMS]) == null ? void 0 : _store$DEV_GET_MOUNTE2.call(store)) || []));
101 };
102 var unsubscribe = (_store$DEV_SUBSCRIBE_ = store[DEV_SUBSCRIBE_STATE]) == null ? void 0 : _store$DEV_SUBSCRIBE_.call(store, callback);
103 callback();
104 return unsubscribe;
105 }, [enabled, store]);
106 react.useDebugValue([store, atoms], stateToPrintable);
107};
108
109function useAtomDevtools(anAtom, options, deprecatedScope) {
110 if (typeof options === 'string' || typeof deprecatedScope !== 'undefined') {
111 console.warn('DEPRECATED [useAtomDevtools] use DevtoolOptions');
112 options = {
113 name: options,
114 scope: deprecatedScope
115 };
116 }
117
118 var _ref = options || {},
119 enabled = _ref.enabled,
120 name = _ref.name,
121 scope = _ref.scope;
122 var extension;
123 try {
124 extension = (enabled != null ? enabled : process.env.NODE_ENV !== "production") && window.__REDUX_DEVTOOLS_EXTENSION__;
125 } catch (_unused) {
126 }
127
128 if (!extension) {
129 if (process.env.NODE_ENV !== "production" && enabled) {
130 console.warn('Please install/enable Redux devtools extension');
131 }
132 }
133 var _useAtom = jotai.useAtom(anAtom, scope),
134 value = _useAtom[0],
135 setValue = _useAtom[1];
136 var lastValue = react.useRef(value);
137 var isTimeTraveling = react.useRef(false);
138 var devtools = react.useRef();
139 var atomName = name || anAtom.debugLabel || anAtom.toString();
140 react.useEffect(function () {
141 if (!extension) {
142 return;
143 }
144 var setValueIfWritable = function setValueIfWritable(value) {
145 if (typeof setValue === 'function') {
146 setValue(value);
147 return;
148 }
149 console.warn('[Warn] you cannot do write operations (Time-travelling, etc) in read-only atoms\n', anAtom);
150 };
151 devtools.current = extension.connect({
152 name: atomName
153 });
154 var unsubscribe = devtools.current.subscribe(function (message) {
155 var _message$payload3, _message$payload4;
156 if (message.type === 'ACTION' && message.payload) {
157 try {
158 setValueIfWritable(JSON.parse(message.payload));
159 } catch (e) {
160 console.error('please dispatch a serializable value that JSON.parse() support\n', e);
161 }
162 } else if (message.type === 'DISPATCH' && message.state) {
163 var _message$payload, _message$payload2;
164 if (((_message$payload = message.payload) == null ? void 0 : _message$payload.type) === 'JUMP_TO_ACTION' || ((_message$payload2 = message.payload) == null ? void 0 : _message$payload2.type) === 'JUMP_TO_STATE') {
165 isTimeTraveling.current = true;
166 setValueIfWritable(JSON.parse(message.state));
167 }
168 } else if (message.type === 'DISPATCH' && ((_message$payload3 = message.payload) == null ? void 0 : _message$payload3.type) === 'COMMIT') {
169 var _devtools$current;
170 (_devtools$current = devtools.current) == null ? void 0 : _devtools$current.init(lastValue.current);
171 } else if (message.type === 'DISPATCH' && ((_message$payload4 = message.payload) == null ? void 0 : _message$payload4.type) === 'IMPORT_STATE') {
172 var _message$payload$next;
173 var computedStates = ((_message$payload$next = message.payload.nextLiftedState) == null ? void 0 : _message$payload$next.computedStates) || [];
174 computedStates.forEach(function (_ref2, index) {
175 var state = _ref2.state;
176 if (index === 0) {
177 var _devtools$current2;
178 (_devtools$current2 = devtools.current) == null ? void 0 : _devtools$current2.init(state);
179 } else {
180 setValueIfWritable(state);
181 }
182 });
183 }
184 });
185 devtools.current.shouldInit = true;
186 return unsubscribe;
187 }, [anAtom, extension, atomName, setValue]);
188 react.useEffect(function () {
189 if (!devtools.current) {
190 return;
191 }
192 lastValue.current = value;
193 if (devtools.current.shouldInit) {
194 devtools.current.init(value);
195 devtools.current.shouldInit = false;
196 } else if (isTimeTraveling.current) {
197 isTimeTraveling.current = false;
198 } else {
199 devtools.current.send(atomName + " - " + new Date().toLocaleString(), value);
200 }
201 }, [anAtom, extension, atomName, value]);
202}
203
204var isEqualAtomsValues = function isEqualAtomsValues(left, right) {
205 return left.size === right.size && Array.from(left).every(function (_ref) {
206 var left = _ref[0],
207 v = _ref[1];
208 return Object.is(right.get(left), v);
209 });
210};
211var isEqualAtomsDependents = function isEqualAtomsDependents(left, right) {
212 return left.size === right.size && Array.from(left).every(function (_ref2) {
213 var a = _ref2[0],
214 dLeft = _ref2[1];
215 var dRight = right.get(a);
216 return dRight && dLeft.size === dRight.size && Array.from(dLeft).every(function (d) {
217 return dRight.has(d);
218 });
219 });
220};
221function useAtomsSnapshot(scope) {
222 var ScopeContext = jotai.SECRET_INTERNAL_getScopeContext(scope);
223 var scopeContainer = react.useContext(ScopeContext);
224 var store = scopeContainer.s;
225 var _useState = react.useState(function () {
226 return {
227 values: new Map(),
228 dependents: new Map()
229 };
230 }),
231 atomsSnapshot = _useState[0],
232 setAtomsSnapshot = _useState[1];
233 react.useEffect(function () {
234 if (!store[DEV_SUBSCRIBE_STATE]) return;
235 var prevValues = new Map();
236 var prevDependents = new Map();
237 var invalidatedAtoms = new Set();
238 var callback = function callback() {
239 var values = new Map();
240 var dependents = new Map();
241 var hasNewInvalidatedAtoms = false;
242 for (var _iterator = _createForOfIteratorHelperLoose(store[DEV_GET_MOUNTED_ATOMS]() || []), _step; !(_step = _iterator()).done;) {
243 var atom = _step.value;
244 var atomState = store[DEV_GET_ATOM_STATE](atom);
245 if (atomState) {
246 if (!atomState.y) {
247 if ('p' in atomState) {
248 return;
249 }
250 if (!invalidatedAtoms.has(atom)) {
251 invalidatedAtoms.add(atom);
252 hasNewInvalidatedAtoms = true;
253 }
254 }
255 if ('v' in atomState) {
256 values.set(atom, atomState.v);
257 }
258 }
259 var mounted = store[DEV_GET_MOUNTED](atom);
260 if (mounted) {
261 dependents.set(atom, mounted.t);
262 }
263 }
264 if (hasNewInvalidatedAtoms) {
265 return;
266 }
267 if (isEqualAtomsValues(prevValues, values) && isEqualAtomsDependents(prevDependents, dependents)) {
268 return;
269 }
270 prevValues = values;
271 prevDependents = dependents;
272 invalidatedAtoms.clear();
273 setAtomsSnapshot({
274 values: values,
275 dependents: dependents
276 });
277 };
278 var unsubscribe = store[DEV_SUBSCRIBE_STATE](callback);
279 callback();
280 return unsubscribe;
281 }, [store]);
282 return atomsSnapshot;
283}
284
285function useGotoAtomsSnapshot(scope) {
286 var ScopeContext = jotai.SECRET_INTERNAL_getScopeContext(scope);
287 var _useContext = react.useContext(ScopeContext),
288 store = _useContext.s,
289 versionedWrite = _useContext.w;
290 return react.useCallback(function (snapshot) {
291 if (!store[DEV_SUBSCRIBE_STATE]) return;
292 var restoreAtoms = function restoreAtoms(values) {
293 if (versionedWrite) {
294 versionedWrite(function (version) {
295 store[RESTORE_ATOMS](values, version);
296 });
297 } else {
298 store[RESTORE_ATOMS](values);
299 }
300 };
301 if (isIterable(snapshot)) {
302 if (process.env.NODE_ENV !== "production") {
303 console.warn('snapshot as iterable is deprecated. use an object instead.');
304 }
305 restoreAtoms(snapshot);
306 return;
307 }
308 restoreAtoms(snapshot.values);
309 }, [store, versionedWrite]);
310}
311var isIterable = function isIterable(item) {
312 return typeof item[Symbol.iterator] === 'function';
313};
314
315var atomToPrintable = function atomToPrintable(atom) {
316 return atom.debugLabel ? atom + ":" + atom.debugLabel : "" + atom;
317};
318var getDevtoolsState = function getDevtoolsState(atomsSnapshot) {
319 var values = {};
320 atomsSnapshot.values.forEach(function (v, atom) {
321 values[atomToPrintable(atom)] = v;
322 });
323 var dependents = {};
324 atomsSnapshot.dependents.forEach(function (d, atom) {
325 dependents[atomToPrintable(atom)] = Array.from(d).map(atomToPrintable);
326 });
327 return {
328 values: values,
329 dependents: dependents
330 };
331};
332function useAtomsDevtools(name, options) {
333 if (typeof options !== 'undefined' && typeof options !== 'object') {
334 console.warn('DEPRECATED [useAtomsDevtools] use DevtoolsOptions');
335 options = {
336 scope: options
337 };
338 }
339 var _ref = options || {},
340 enabled = _ref.enabled,
341 scope = _ref.scope;
342 var extension;
343 try {
344 extension = (enabled != null ? enabled : process.env.NODE_ENV !== "production") && window.__REDUX_DEVTOOLS_EXTENSION__;
345 } catch (_unused) {
346 }
347
348 if (!extension) {
349 if (process.env.NODE_ENV !== "production" && enabled) {
350 console.warn('Please install/enable Redux devtools extension');
351 }
352 }
353
354 var atomsSnapshot = useAtomsSnapshot(scope);
355 var goToSnapshot = useGotoAtomsSnapshot(scope);
356 var isTimeTraveling = react.useRef(false);
357 var isRecording = react.useRef(true);
358 var devtools = react.useRef();
359 var snapshots = react.useRef([]);
360 react.useEffect(function () {
361 if (!extension) {
362 return;
363 }
364 var getSnapshotAt = function getSnapshotAt(index) {
365 if (index === void 0) {
366 index = snapshots.current.length - 1;
367 }
368 var snapshot = snapshots.current[index >= 0 ? index : 0];
369 if (!snapshot) {
370 throw new Error('snaphost index out of bounds');
371 }
372 return snapshot;
373 };
374 var connection = extension.connect({
375 name: name
376 });
377 var devtoolsUnsubscribe = connection.subscribe(function (message) {
378 var _message$payload;
379 switch (message.type) {
380 case 'DISPATCH':
381 switch ((_message$payload = message.payload) == null ? void 0 : _message$payload.type) {
382 case 'RESET':
383 break;
384 case 'COMMIT':
385 connection.init(getDevtoolsState(getSnapshotAt()));
386 snapshots.current = [];
387 break;
388 case 'JUMP_TO_ACTION':
389 case 'JUMP_TO_STATE':
390 isTimeTraveling.current = true;
391 goToSnapshot(getSnapshotAt(message.payload.actionId - 1));
392 break;
393 case 'PAUSE_RECORDING':
394 isRecording.current = !isRecording.current;
395 break;
396 }
397 }
398 });
399 devtools.current = connection;
400 devtools.current.shouldInit = true;
401 return function () {
402 extension.disconnect();
403 devtoolsUnsubscribe == null ? void 0 : devtoolsUnsubscribe();
404 };
405 }, [extension, goToSnapshot, name]);
406 react.useEffect(function () {
407 if (!devtools.current) {
408 return;
409 }
410 if (devtools.current.shouldInit) {
411 devtools.current.init(undefined);
412 devtools.current.shouldInit = false;
413 return;
414 }
415 if (isTimeTraveling.current) {
416 isTimeTraveling.current = false;
417 } else if (isRecording.current) {
418 snapshots.current.push(atomsSnapshot);
419 devtools.current.send({
420 type: "" + snapshots.current.length,
421 updatedAt: new Date().toLocaleString()
422 }, getDevtoolsState(atomsSnapshot));
423 }
424 }, [atomsSnapshot]);
425}
426
427exports.useAtomDevtools = useAtomDevtools;
428exports.useAtomsDebugValue = useAtomsDebugValue;
429exports.useAtomsDevtools = useAtomsDevtools;
430exports.useAtomsSnapshot = useAtomsSnapshot;
431exports.useGotoAtomsSnapshot = useGotoAtomsSnapshot;