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