atom.io 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,880 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __objRest = (source, exclude) => {
21
- var target = {};
22
- for (var prop in source)
23
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
- target[prop] = source[prop];
25
- if (source != null && __getOwnPropSymbols)
26
- for (var prop of __getOwnPropSymbols(source)) {
27
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
- target[prop] = source[prop];
29
- }
30
- return target;
31
- };
32
- var __export = (target, all) => {
33
- for (var name in all)
34
- __defProp(target, name, { get: all[name], enumerable: true });
35
- };
36
-
37
- // src/internal/index.ts
38
- var internal_exports = {};
39
- __export(internal_exports, {
40
- IMPLICIT: () => IMPLICIT,
41
- abortTransaction: () => abortTransaction,
42
- clearStore: () => clearStore,
43
- configure: () => configure,
44
- createStore: () => createStore,
45
- deposit: () => deposit,
46
- evictDownStream: () => evictDownStream,
47
- finishAction: () => finishAction,
48
- finishTransaction: () => finishTransaction,
49
- getCachedState: () => getCachedState,
50
- getSelectorState: () => getSelectorState,
51
- getState__INTERNAL: () => getState__INTERNAL,
52
- isAtomDefault: () => isAtomDefault,
53
- isDone: () => isDone,
54
- isSelectorDefault: () => isSelectorDefault,
55
- lookup: () => lookup,
56
- lookupSelectorSources: () => lookupSelectorSources,
57
- markDone: () => markDone,
58
- recallState: () => recallState,
59
- registerSelector: () => registerSelector,
60
- setAtomState: () => setAtomState,
61
- setSelectorState: () => setSelectorState,
62
- setState__INTERNAL: () => setState__INTERNAL,
63
- startAction: () => startAction,
64
- startTransaction: () => startTransaction,
65
- subscribeToRootAtoms: () => subscribeToRootAtoms,
66
- traceAllSelectorAtoms: () => traceAllSelectorAtoms,
67
- traceSelectorAtoms: () => traceSelectorAtoms,
68
- updateSelectorAtoms: () => updateSelectorAtoms,
69
- withdraw: () => withdraw
70
- });
71
-
72
- // src/internal/get.ts
73
- import { pipe as pipe6 } from "fp-ts/function";
74
- import HAMT2 from "hamt_plus";
75
-
76
- // src/internal/store.ts
77
- import HAMT from "hamt_plus";
78
-
79
- // ../anvl/src/join/core-relation-data.ts
80
- import { isString } from "fp-ts/string";
81
-
82
- // ../anvl/src/array/venn.ts
83
- var includesAll = (items) => (array) => {
84
- for (const item of items) {
85
- if (!array.includes(item))
86
- return false;
87
- }
88
- return true;
89
- };
90
- var comprises = (items) => (array) => includesAll(items)(array) && includesAll(array)(items);
91
-
92
- // ../anvl/src/array/index.ts
93
- var isArray = (isType) => (input) => Array.isArray(input) && input.every((item) => isType(item));
94
- var map = (f) => (a) => a.map(f);
95
- var every = (f = Boolean) => (a) => a.every(f);
96
- var allTrue = every((x) => x === true);
97
- var addTo = (a) => (x) => a.includes(x) ? a : [...a, x];
98
- var isEmptyArray = (input) => Array.isArray(input) && input.length === 0;
99
- var isOneOf = (...args) => (input) => args.includes(input);
100
-
101
- // ../anvl/src/object/refinement.ts
102
- import { pipe as pipe2 } from "fp-ts/function";
103
-
104
- // ../anvl/src/object/access.ts
105
- var access = (k) => Object.assign((obj) => obj[k], {
106
- in: (obj) => obj[k]
107
- });
108
-
109
- // ../anvl/src/object/entries.ts
110
- var recordToEntries = (obj) => Object.entries(obj);
111
- var entriesToRecord = (entries) => Object.fromEntries(entries);
112
-
113
- // ../anvl/src/object/mapObject.ts
114
- import { pipe } from "fp-ts/lib/function";
115
- var mapObject = (obj, fn) => pipe(
116
- obj,
117
- recordToEntries,
118
- map(([key, val]) => [key, fn(val, key)]),
119
- entriesToRecord
120
- );
121
- var mob = (fn) => (obj) => mapObject(obj, fn);
122
-
123
- // ../anvl/src/function/index.ts
124
- var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
125
- originalThing instanceof Function ? originalThing() : originalThing
126
- ) : nextVersionOfThing;
127
- var pass = (...params) => (fn) => fn(...params);
128
-
129
- // ../anvl/src/nullish/index.ts
130
- var isUndefined = (input) => input === void 0;
131
- var ifNullish = (alt) => (input) => input != null ? input : alt;
132
-
133
- // ../anvl/src/object/refinement.ts
134
- var isNonNullObject = (input) => typeof input === `object` && input !== null;
135
- var isPlainObject = (input) => isNonNullObject(input) && Object.getPrototypeOf(input) === Object.prototype;
136
- var isEmptyObject = (input) => isPlainObject(input) && Object.keys(input).length === 0;
137
- var isRecord = (isKey, isValue) => (input) => isPlainObject(input) && Object.entries(input).every(([k, v]) => isKey(k) && isValue(v));
138
- var hasProperties = (isValue, options = { allowExtraProperties: false }) => {
139
- const name = `{${recordToEntries(
140
- isValue
141
- ).map(([k, v]) => String(k) + `:` + v.name).join(`,`)}}`;
142
- const _ = {
143
- [name]: (input) => isPlainObject(input) && pipe2(
144
- isValue,
145
- Object.entries,
146
- every(([key, val]) => key in input || val(void 0))
147
- ) && pipe2(
148
- input,
149
- mob(
150
- (val, key) => pipe2(
151
- isValue,
152
- access(key),
153
- ifNullish(() => options.allowExtraProperties),
154
- pass(val)
155
- )
156
- ),
157
- Object.values,
158
- allTrue
159
- )
160
- };
161
- return _[name];
162
- };
163
- var hasExactProperties = (
164
- /* alias for hasProperties without allowExtraProperties */
165
- (isValue) => hasProperties(isValue, { allowExtraProperties: false })
166
- );
167
-
168
- // ../anvl/src/join/core-relation-data.ts
169
- var RELATION_TYPES = [`1:1`, `1:n`, `n:n`];
170
- var isRelationType = (x) => RELATION_TYPES.includes(x);
171
- var EMPTY_RELATION_DATA = {
172
- contents: {},
173
- relations: {},
174
- relationType: `n:n`
175
- };
176
- var isRelationData = (isContent) => (input) => hasExactProperties({
177
- contents: isContent ? isRecord(isString, isContent) : hasExactProperties({}),
178
- relations: isRecord(isString, isArray(isString)),
179
- relationType: isRelationType
180
- })(input);
181
-
182
- // ../anvl/src/join/get-related-ids.ts
183
- var getRelatedIds = (relationMap, id) => {
184
- var _a;
185
- return (_a = relationMap.relations[id]) != null ? _a : [];
186
- };
187
- var getRelatedId = (relationMap, id) => {
188
- const relations = getRelatedIds(relationMap, id);
189
- if (relations.length > 1) {
190
- console.warn(
191
- `entry with id ${id} was not expected to have multiple relations`
192
- );
193
- }
194
- return relations[0];
195
- };
196
-
197
- // ../anvl/src/join/relation-contents.ts
198
- import { pipe as pipe5 } from "fp-ts/function";
199
-
200
- // ../anvl/src/join/relation-record.ts
201
- var getRelationEntries = (relationMap, idA) => getRelatedIds(relationMap, idA).map((idB) => [
202
- idB,
203
- getContent(relationMap, idA, idB)
204
- ]);
205
- var getRelationRecord = (relationMap, id) => Object.fromEntries(getRelationEntries(relationMap, id));
206
-
207
- // ../anvl/src/join/remove-relation.ts
208
- import { pipe as pipe4 } from "fp-ts/function";
209
- import { isString as isString2 } from "fp-ts/string";
210
-
211
- // ../anvl/src/object/index.ts
212
- import { pipe as pipe3 } from "fp-ts/function";
213
- var treeShake = (shouldDiscard = isUndefined) => (obj) => {
214
- const newObj = {};
215
- const entries = Object.entries(obj);
216
- entries.forEach(
217
- ([key, val]) => !shouldDiscard(val, key) ? newObj[key] = val : null
218
- );
219
- return newObj;
220
- };
221
-
222
- // ../anvl/src/string/split.ts
223
- var split = (separator) => (str) => str.split(separator);
224
-
225
- // ../anvl/src/join/remove-relation.ts
226
- var removeSpecific = (current, idA, idB) => {
227
- const isIdForRemoval = isOneOf(idA, idB);
228
- return __spreadProps(__spreadValues({}, current), {
229
- relations: pipe4(
230
- current.relations,
231
- recordToEntries,
232
- map(([id, relations]) => [
233
- id,
234
- isIdForRemoval(id) ? relations.filter((relation) => !isIdForRemoval(relation)) : relations
235
- ]),
236
- entriesToRecord,
237
- treeShake(isEmptyArray)
238
- ),
239
- contents: pipe4(
240
- current.contents,
241
- treeShake(
242
- (_, key) => isString2(key) && pipe4(key, split(`/`), comprises([idA, idB]))
243
- )
244
- )
245
- });
246
- };
247
- var removeAll = (current, idToRemove) => {
248
- const next = __spreadProps(__spreadValues({}, current), {
249
- relations: pipe4(
250
- current.relations,
251
- recordToEntries,
252
- map(([id, relations]) => [
253
- id,
254
- relations.filter((relation) => relation !== idToRemove)
255
- ]),
256
- entriesToRecord,
257
- treeShake((val, key) => key === idToRemove || isEmptyArray(val))
258
- ),
259
- contents: pipe4(
260
- current.contents,
261
- treeShake(
262
- (_, key) => isString2(key) && key.split(`/`).includes(idToRemove)
263
- )
264
- )
265
- });
266
- return next;
267
- };
268
- var removeRelation = (current, idA, idB) => idB ? removeSpecific(current, idA, idB) : removeAll(current, idA);
269
-
270
- // ../anvl/src/join/set-relation.ts
271
- var setManyToMany = (map2, idA, idB, ...rest) => {
272
- var _a, _b;
273
- const next = __spreadProps(__spreadValues({}, map2), {
274
- relations: __spreadProps(__spreadValues({}, map2.relations), {
275
- [idA]: addTo((_a = map2.relations[idA]) != null ? _a : [])(idB),
276
- [idB]: addTo((_b = map2.relations[idB]) != null ? _b : [])(idA)
277
- })
278
- });
279
- const content = rest[0];
280
- return content ? setContent(next, idA, idB, content) : next;
281
- };
282
- var removeEmpties = treeShake(isEmptyArray);
283
- var set1ToMany = (current, leaderId, followerId, ...rest) => {
284
- var _a;
285
- const relations = __spreadValues({}, current.relations);
286
- const prevLeaderId = getRelatedId(current, followerId);
287
- const next = __spreadProps(__spreadValues({}, current), {
288
- relations: removeEmpties(__spreadProps(__spreadValues(__spreadValues({}, relations), prevLeaderId && prevLeaderId !== leaderId && {
289
- [prevLeaderId]: relations[prevLeaderId].filter(
290
- (id) => id !== followerId
291
- )
292
- }), {
293
- [followerId]: [leaderId],
294
- [leaderId]: addTo((_a = relations[leaderId]) != null ? _a : [])(followerId)
295
- }))
296
- });
297
- const content = rest[0];
298
- return content ? setContent(next, leaderId, followerId, content) : next;
299
- };
300
- var set1To1 = (current, wifeId, husbandId, ...rest) => {
301
- const prevWifeId = getRelatedId(current, husbandId);
302
- const prevHusbandId = getRelatedId(current, wifeId);
303
- const next = __spreadProps(__spreadValues({}, current), {
304
- relations: removeEmpties(__spreadProps(__spreadValues(__spreadValues(__spreadValues({}, current.relations), prevWifeId && { [prevWifeId]: [] }), prevHusbandId && { [prevHusbandId]: [] }), {
305
- [wifeId]: [husbandId],
306
- [husbandId]: [wifeId]
307
- }))
308
- });
309
- const content = rest[0];
310
- return content ? setContent(next, wifeId, husbandId, content) : next;
311
- };
312
- var setRelationWithContent = (current, idA, idB, ...rest) => {
313
- switch (current.relationType) {
314
- case `1:1`:
315
- return set1To1(current, idA, idB, ...rest);
316
- case `1:n`:
317
- return set1ToMany(current, idA, idB, ...rest);
318
- case `n:n`:
319
- return setManyToMany(current, idA, idB, ...rest);
320
- }
321
- };
322
-
323
- // ../anvl/src/join/relation-contents.ts
324
- var makeContentId = (idA, idB) => [idA, idB].sort().join(`/`);
325
- var getContent = (relationMap, idA, idB) => relationMap.contents[makeContentId(idA, idB)];
326
- var setContent = (map2, idA, idB, content) => __spreadProps(__spreadValues({}, map2), {
327
- contents: __spreadProps(__spreadValues({}, map2.contents), {
328
- [makeContentId(idA, idB)]: content
329
- })
330
- });
331
- var getRelations = (relationMap, id) => getRelationEntries(relationMap, id).map(
332
- ([id2, content]) => __spreadValues({
333
- id: id2
334
- }, content)
335
- );
336
- var setRelations = (current, idA, relations) => pipe5(
337
- current,
338
- (relationData) => {
339
- const relatedIds = getRelatedIds(current, idA);
340
- const removedIds = relatedIds.filter(
341
- (id) => !relations.some((r) => r.id === id)
342
- );
343
- let step = relationData;
344
- for (const idB of removedIds)
345
- step = removeRelation(step, idA, idB);
346
- return step;
347
- },
348
- (relationData) => {
349
- let step = relationData;
350
- for (const _a of relations) {
351
- const _b = _a, { id: idB } = _b, rest = __objRest(_b, ["id"]);
352
- const content = isEmptyObject(rest) ? void 0 : rest;
353
- step = setRelationWithContent(step, idA, idB, content);
354
- }
355
- return step;
356
- },
357
- (relationData) => {
358
- const newlyOrderedIds = relations.map((r) => r.id);
359
- return __spreadProps(__spreadValues({}, relationData), {
360
- relations: __spreadProps(__spreadValues({}, relationData.relations), {
361
- [idA]: newlyOrderedIds
362
- })
363
- });
364
- }
365
- );
366
-
367
- // ../anvl/src/refinement/index.ts
368
- var canExist = (_) => true;
369
- var cannotExist = (_) => false;
370
- var couldBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
371
- const name = `(${refinements.map((r) => r.name || `anon`).join(` | `)})`;
372
- const _ = {
373
- [name]: (input) => refinements.some(
374
- (refinement) => {
375
- var _a;
376
- return logging && console.log(
377
- refinements.map((r) => r.name || `anon`).join(` | `),
378
- `>`,
379
- (_a = refinement.name) != null ? _a : `anon`,
380
- `:`,
381
- refinement(input)
382
- ), refinement(input);
383
- }
384
- )
385
- };
386
- const checkTypes = Object.assign(_[name], {
387
- or: (isTypeB) => couldBe(isTypeB, logging, [...refinements, isTypeB])
388
- });
389
- return checkTypes;
390
- };
391
- var isUnion = couldBe(cannotExist);
392
- var mustBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
393
- const name = `(${refinements.map((r) => r.name || `anon`).join(` & `)})`;
394
- const _ = {
395
- [name]: (input) => refinements.every(
396
- (refinement) => (logging && console.log(
397
- refinements.map((r) => r.name || `anon`).join(` & `),
398
- `>`,
399
- refinement.name || `anon`,
400
- `:`,
401
- refinement(input)
402
- ), refinement(input))
403
- )
404
- };
405
- const checkTypes = Object.assign(_[name], {
406
- and: (isTypeB) => mustBe(isTypeB, logging, [...refinements, isTypeB])
407
- });
408
- return checkTypes;
409
- };
410
- var isIntersection = mustBe(canExist);
411
-
412
- // ../anvl/src/join/index.ts
413
- var Join = class {
414
- constructor(json) {
415
- Object.assign(this, __spreadValues(__spreadValues({}, EMPTY_RELATION_DATA), json));
416
- }
417
- toJSON() {
418
- return {
419
- relationType: this.relationType,
420
- relations: this.relations,
421
- contents: this.contents
422
- };
423
- }
424
- static fromJSON(json, isContent = cannotExist) {
425
- const isValid = isRelationData(isContent)(json);
426
- if (isValid) {
427
- return new Join(json);
428
- }
429
- throw new Error(
430
- `Saved JSON for this Join is invalid: ${JSON.stringify(json)}`
431
- );
432
- }
433
- getRelatedId(id) {
434
- return getRelatedId(this, id);
435
- }
436
- getRelatedIds(id) {
437
- return getRelatedIds(this, id);
438
- }
439
- getContent(idA, idB) {
440
- return getContent(this, idA, idB);
441
- }
442
- getRelationEntries(id) {
443
- return getRelationEntries(this, id);
444
- }
445
- getRelationRecord(id) {
446
- return getRelationRecord(this, id);
447
- }
448
- getRelation(id) {
449
- return getRelations(this, id)[0];
450
- }
451
- getRelations(id) {
452
- return getRelations(this, id);
453
- }
454
- setRelations(id, relations) {
455
- return new Join(setRelations(this, id, relations));
456
- }
457
- set(idA, idB, ...rest) {
458
- return new Join(setRelationWithContent(this, idA, idB, ...rest));
459
- }
460
- remove(idA, idB) {
461
- return new Join(removeRelation(this, idA, idB));
462
- }
463
- };
464
-
465
- // src/internal/store.ts
466
- var createStore = (name) => ({
467
- valueMap: HAMT.make(),
468
- selectorGraph: new Join({ relationType: `n:n` }),
469
- selectorAtoms: new Join({ relationType: `n:n` }),
470
- atoms: HAMT.make(),
471
- atomsAreDefault: HAMT.make(),
472
- selectors: HAMT.make(),
473
- readonlySelectors: HAMT.make(),
474
- operation: {
475
- open: false
476
- },
477
- transaction: {
478
- open: false
479
- },
480
- config: {
481
- name,
482
- logger: null
483
- }
484
- });
485
- var IMPLICIT = {
486
- STORE_INTERNAL: void 0,
487
- get STORE() {
488
- var _a;
489
- return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = createStore(`DEFAULT`);
490
- }
491
- };
492
- var configure = (config, store = IMPLICIT.STORE) => {
493
- Object.assign(store.config, config);
494
- };
495
- var clearStore = (store = IMPLICIT.STORE) => {
496
- const { config } = store;
497
- Object.assign(store, createStore(config.name));
498
- store.config = config;
499
- };
500
-
501
- // src/internal/get.ts
502
- var getCachedState = (state, store = IMPLICIT.STORE) => {
503
- const path = [];
504
- if (`default` in state) {
505
- const atomKey = state.key;
506
- store.selectorAtoms = pipe6(store.selectorAtoms, (oldValue) => {
507
- let newValue = oldValue;
508
- for (const selectorKey of path) {
509
- newValue = newValue.set(selectorKey, atomKey);
510
- }
511
- return newValue;
512
- });
513
- }
514
- const value = HAMT2.get(state.key, store.valueMap);
515
- return value;
516
- };
517
- var getSelectorState = (selector) => selector.get();
518
- function lookup(key, store) {
519
- const type = HAMT2.has(key, store.atoms) ? `atom` : HAMT2.has(key, store.selectors) ? `selector` : `readonly_selector`;
520
- return { key, type };
521
- }
522
- function withdraw(token, store) {
523
- var _a, _b;
524
- return (_b = (_a = HAMT2.get(token.key, store.atoms)) != null ? _a : HAMT2.get(token.key, store.selectors)) != null ? _b : HAMT2.get(token.key, store.readonlySelectors);
525
- }
526
- function deposit(state) {
527
- if (`get` in state) {
528
- if (`set` in state) {
529
- return { key: state.key, type: `selector` };
530
- }
531
- return { key: state.key, type: `readonly_selector` };
532
- }
533
- return { key: state.key, type: `atom` };
534
- }
535
- var getState__INTERNAL = (state, store = IMPLICIT.STORE) => {
536
- var _a, _b, _c;
537
- if (HAMT2.has(state.key, store.valueMap)) {
538
- (_a = store.config.logger) == null ? void 0 : _a.info(`>> read "${state.key}"`);
539
- return getCachedState(state, store);
540
- }
541
- if (`get` in state) {
542
- (_b = store.config.logger) == null ? void 0 : _b.info(`-> calc "${state.key}"`);
543
- return getSelectorState(state);
544
- }
545
- (_c = store.config.logger) == null ? void 0 : _c.error(
546
- `Attempted to get atom "${state.key}", which was never initialized in store "${store.config.name}".`
547
- );
548
- return state.default;
549
- };
550
-
551
- // src/internal/set.ts
552
- import HAMT4 from "hamt_plus";
553
-
554
- // src/internal/operation.ts
555
- import HAMT3 from "hamt_plus";
556
- var startAction = (store) => {
557
- var _a;
558
- store.operation = {
559
- open: true,
560
- done: /* @__PURE__ */ new Set(),
561
- prev: store.valueMap
562
- };
563
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u2B55`, `operation start`);
564
- };
565
- var finishAction = (store) => {
566
- var _a;
567
- store.operation = { open: false };
568
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F534}`, `operation done`);
569
- };
570
- var isDone = (key, store = IMPLICIT.STORE) => {
571
- var _a;
572
- if (!store.operation.open) {
573
- (_a = store.config.logger) == null ? void 0 : _a.warn(
574
- `isDone called outside of an action. This is probably a bug.`
575
- );
576
- return true;
577
- }
578
- return store.operation.done.has(key);
579
- };
580
- var markDone = (key, store = IMPLICIT.STORE) => {
581
- var _a;
582
- if (!store.operation.open) {
583
- (_a = store.config.logger) == null ? void 0 : _a.warn(
584
- `markDone called outside of an action. This is probably a bug.`
585
- );
586
- return;
587
- }
588
- store.operation.done.add(key);
589
- };
590
- var recallState = (state, store = IMPLICIT.STORE) => {
591
- var _a;
592
- if (!store.operation.open) {
593
- (_a = store.config.logger) == null ? void 0 : _a.warn(
594
- `recall called outside of an action. This is probably a bug.`
595
- );
596
- return HAMT3.get(state.key, store.valueMap);
597
- }
598
- return HAMT3.get(state.key, store.operation.prev);
599
- };
600
-
601
- // src/internal/set.ts
602
- var evictDownStream = (state, store = IMPLICIT.STORE) => {
603
- var _a, _b;
604
- const downstream = store.selectorAtoms.getRelations(state.key);
605
- const downstreamKeys = downstream.map(({ id }) => id);
606
- (_a = store.config.logger) == null ? void 0 : _a.info(
607
- ` || ${downstreamKeys.length} downstream:`,
608
- downstreamKeys
609
- );
610
- if (store.operation.open) {
611
- (_b = store.config.logger) == null ? void 0 : _b.info(` ||`, [...store.operation.done], `already done`);
612
- }
613
- downstream.forEach(({ id: stateKey }) => {
614
- var _a2, _b2, _c, _d;
615
- if (isDone(stateKey, store)) {
616
- (_a2 = store.config.logger) == null ? void 0 : _a2.info(` || ${stateKey} already done`);
617
- return;
618
- }
619
- const state2 = (_b2 = HAMT4.get(stateKey, store.selectors)) != null ? _b2 : HAMT4.get(stateKey, store.readonlySelectors);
620
- if (!state2) {
621
- (_c = store.config.logger) == null ? void 0 : _c.info(
622
- ` || ${stateKey} is an atom, and can't be downstream`
623
- );
624
- return;
625
- }
626
- store.valueMap = HAMT4.remove(stateKey, store.valueMap);
627
- (_d = store.config.logger) == null ? void 0 : _d.info(` xx evicted "${stateKey}"`);
628
- markDone(stateKey, store);
629
- });
630
- };
631
- var setAtomState = (atom, next, store = IMPLICIT.STORE) => {
632
- var _a, _b;
633
- const oldValue = getState__INTERNAL(atom, store);
634
- const newValue = become(next)(oldValue);
635
- (_a = store.config.logger) == null ? void 0 : _a.info(`-> setting atom "${atom.key}" to`, newValue);
636
- store.valueMap = HAMT4.set(atom.key, newValue, store.valueMap);
637
- if (isAtomDefault(atom.key)) {
638
- store.atomsAreDefault = HAMT4.set(atom.key, false, store.atomsAreDefault);
639
- }
640
- markDone(atom.key, store);
641
- (_b = store.config.logger) == null ? void 0 : _b.info(
642
- ` || evicting caches downstream from "${atom.key}"`
643
- );
644
- evictDownStream(atom, store);
645
- atom.subject.next({ newValue, oldValue });
646
- };
647
- var setSelectorState = (selector, next, store = IMPLICIT.STORE) => {
648
- var _a, _b;
649
- const oldValue = getState__INTERNAL(selector, store);
650
- const newValue = become(next)(oldValue);
651
- (_a = store.config.logger) == null ? void 0 : _a.info(`-> setting selector "${selector.key}" to`, newValue);
652
- (_b = store.config.logger) == null ? void 0 : _b.info(` || propagating change made to "${selector.key}"`);
653
- selector.set(newValue);
654
- };
655
- var setState__INTERNAL = (state, value, store = IMPLICIT.STORE) => {
656
- if (`set` in state) {
657
- setSelectorState(state, value, store);
658
- } else {
659
- setAtomState(state, value, store);
660
- }
661
- };
662
-
663
- // src/internal/is-default.ts
664
- import HAMT5 from "hamt_plus";
665
- var isAtomDefault = (key, store = IMPLICIT.STORE) => {
666
- return HAMT5.get(key, store.atomsAreDefault);
667
- };
668
- var isSelectorDefault = (key, store = IMPLICIT.STORE) => {
669
- const roots = traceAllSelectorAtoms(key, store);
670
- return roots.every((root) => isAtomDefault(root.key, store));
671
- };
672
-
673
- // src/internal/selector-internal.ts
674
- var lookupSelectorSources = (key, store) => store.selectorGraph.getRelations(key).filter(({ source }) => source !== key).map(({ source }) => lookup(source, store));
675
- var traceSelectorAtoms = (selectorKey, dependency, store) => {
676
- const roots = [];
677
- const sources = lookupSelectorSources(dependency.key, store);
678
- let depth = 0;
679
- while (sources.length > 0) {
680
- const source = sources.shift();
681
- ++depth;
682
- if (depth > 999) {
683
- throw new Error(
684
- `Maximum selector dependency depth exceeded in selector "${selectorKey}".`
685
- );
686
- }
687
- if (source.type !== `atom`) {
688
- sources.push(...lookupSelectorSources(source.key, store));
689
- } else {
690
- roots.push(source);
691
- }
692
- }
693
- return roots;
694
- };
695
- var traceAllSelectorAtoms = (selectorKey, store) => {
696
- const sources = lookupSelectorSources(selectorKey, store);
697
- return sources.flatMap(
698
- (source) => source.type === `atom` ? source : traceSelectorAtoms(selectorKey, source, store)
699
- );
700
- };
701
- var updateSelectorAtoms = (selectorKey, dependency, store) => {
702
- var _a, _b;
703
- if (dependency.type === `atom`) {
704
- store.selectorAtoms = store.selectorAtoms.set(selectorKey, dependency.key);
705
- (_a = store.config.logger) == null ? void 0 : _a.info(
706
- ` || adding root for "${selectorKey}": ${dependency.key}`
707
- );
708
- return;
709
- }
710
- const roots = traceSelectorAtoms(selectorKey, dependency, store);
711
- (_b = store.config.logger) == null ? void 0 : _b.info(` || adding roots for "${selectorKey}":`, roots);
712
- for (const root of roots) {
713
- store.selectorAtoms = store.selectorAtoms.set(selectorKey, root.key);
714
- }
715
- };
716
- var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
717
- get: (dependency) => {
718
- var _a, _b;
719
- const alreadyRegistered = store.selectorGraph.getRelations(selectorKey).some(({ source }) => source === dependency.key);
720
- const dependencyState = withdraw(dependency, store);
721
- const dependencyValue = getState__INTERNAL(dependencyState, store);
722
- if (alreadyRegistered) {
723
- (_a = store.config.logger) == null ? void 0 : _a.info(
724
- ` || ${selectorKey} <- ${dependency.key} =`,
725
- dependencyValue
726
- );
727
- } else {
728
- (_b = store.config.logger) == null ? void 0 : _b.info(
729
- `\u{1F50C} registerSelector "${selectorKey}" <- "${dependency.key}" =`,
730
- dependencyValue
731
- );
732
- store.selectorGraph = store.selectorGraph.set(
733
- selectorKey,
734
- dependency.key,
735
- {
736
- source: dependency.key
737
- }
738
- );
739
- }
740
- updateSelectorAtoms(selectorKey, dependency, store);
741
- return dependencyValue;
742
- },
743
- set: (stateToken, newValue) => {
744
- const state = withdraw(stateToken, store);
745
- setState__INTERNAL(state, newValue, store);
746
- }
747
- });
748
-
749
- // src/internal/subscribe-internal.ts
750
- var subscribeToRootAtoms = (state, store = IMPLICIT.STORE) => {
751
- const dependencySubscriptions = `default` in state ? null : traceAllSelectorAtoms(state.key, store).map((atomToken) => {
752
- const atom = withdraw(atomToken, store);
753
- return atom.subject.subscribe((atomChange) => {
754
- var _a, _b;
755
- (_a = store.config.logger) == null ? void 0 : _a.info(
756
- `\u{1F4E2} atom changed: "${atomToken.key}" (`,
757
- atomChange.oldValue,
758
- `->`,
759
- atomChange.newValue,
760
- `) re-evaluating "${state.key}"`
761
- );
762
- const oldValue = recallState(state, store);
763
- const newValue = getState__INTERNAL(state, store);
764
- (_b = store.config.logger) == null ? void 0 : _b.info(` <- ${state.key} became`, newValue);
765
- state.subject.next({ newValue, oldValue });
766
- });
767
- });
768
- return dependencySubscriptions;
769
- };
770
-
771
- // src/internal/transaction-internal.ts
772
- var finishTransaction = (store) => {
773
- var _a;
774
- store.transaction = { open: false };
775
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F6EC}`, `transaction done`);
776
- };
777
- var startTransaction = (store) => {
778
- var _a;
779
- store.transaction = {
780
- open: true,
781
- prev: {
782
- atoms: store.atoms,
783
- readonlySelectors: store.readonlySelectors,
784
- selectorGraph: store.selectorGraph,
785
- selectors: store.selectors,
786
- valueMap: store.valueMap
787
- }
788
- };
789
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F6EB}`, `transaction start`);
790
- };
791
- var abortTransaction = (store) => {
792
- var _a, _b;
793
- if (!store.transaction.open) {
794
- (_a = store.config.logger) == null ? void 0 : _a.warn(
795
- `abortTransaction called outside of a transaction. This is probably a bug.`
796
- );
797
- return;
798
- }
799
- store.atoms = store.transaction.prev.atoms;
800
- store.readonlySelectors = store.transaction.prev.readonlySelectors;
801
- store.selectorGraph = store.transaction.prev.selectorGraph;
802
- store.selectors = store.transaction.prev.selectors;
803
- store.valueMap = store.transaction.prev.valueMap;
804
- store.transaction = { open: false };
805
- (_b = store.config.logger) == null ? void 0 : _b.info(`\u{1FA82}`, `transaction fail`);
806
- };
807
-
808
- // src/index.ts
809
- var setState = (token, value, store = IMPLICIT.STORE) => {
810
- startAction(store);
811
- const state = withdraw(token, store);
812
- setState__INTERNAL(state, value, store);
813
- finishAction(store);
814
- };
815
- var subscribe = (token, observe, store = IMPLICIT.STORE) => {
816
- var _a;
817
- const state = withdraw(token, store);
818
- const subscription = state.subject.subscribe(observe);
819
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F440} subscribe to "${state.key}"`);
820
- const dependencySubscriptions = subscribeToRootAtoms(state, store);
821
- const unsubscribe = dependencySubscriptions === null ? () => {
822
- var _a2;
823
- (_a2 = store.config.logger) == null ? void 0 : _a2.info(`\u{1F648} unsubscribe from "${state.key}"`);
824
- subscription.unsubscribe();
825
- } : () => {
826
- var _a2;
827
- (_a2 = store.config.logger) == null ? void 0 : _a2.info(
828
- `\u{1F648} unsubscribe from "${state.key}" and its dependencies`
829
- );
830
- subscription.unsubscribe();
831
- for (const dependencySubscription of dependencySubscriptions) {
832
- dependencySubscription.unsubscribe();
833
- }
834
- };
835
- return unsubscribe;
836
- };
837
-
838
- // src/react/index.ts
839
- var composeStoreHooks = ({
840
- useState,
841
- useEffect,
842
- store = internal_exports.IMPLICIT.STORE
843
- }) => {
844
- function useI(token) {
845
- const updateState = (next) => setState(token, next, store);
846
- return updateState;
847
- }
848
- function useO(token) {
849
- const state = withdraw(token, store);
850
- const initialValue = internal_exports.getState__INTERNAL(state, store);
851
- const [current, dispatch] = useState(initialValue);
852
- useEffect(() => {
853
- const unsubscribe = subscribe(
854
- token,
855
- ({ newValue, oldValue }) => {
856
- if (oldValue !== newValue) {
857
- dispatch(newValue);
858
- }
859
- },
860
- store
861
- );
862
- return unsubscribe;
863
- }, [current, dispatch]);
864
- return current;
865
- }
866
- function useIO(token) {
867
- return [useO(token), useI(token)];
868
- }
869
- function useStore(token) {
870
- if (token.type === `readonly_selector`) {
871
- return useO(token);
872
- }
873
- return useIO(token);
874
- }
875
- return { useI, useO, useIO, useStore };
876
- };
877
- export {
878
- composeStoreHooks
879
- };
880
- //# sourceMappingURL=index.mjs.map