atom.io 0.27.3 → 0.27.4

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.
@@ -202,7 +202,7 @@ var readOrComputeValue = (state, target) => {
202
202
  target.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
203
203
  return readCachedValue(state, target);
204
204
  }
205
- if (state.type !== `atom` && state.type !== `mutable_atom`) {
205
+ if (state.type === `selector` || state.type === `readonly_selector`) {
206
206
  target.logger.info(`\u{1F9EE}`, state.type, state.key, `computing value`);
207
207
  return state.get();
208
208
  }
@@ -481,6 +481,7 @@ function createRegularAtomFamily(options, store, internalRoles) {
481
481
  internalRoles
482
482
  });
483
483
  store.families.set(options.key, atomFamily);
484
+ store.defaults.set(options.key, options.default);
484
485
  return familyToken;
485
486
  }
486
487
 
@@ -492,8 +493,6 @@ function createAtomFamily(options, store) {
492
493
  }
493
494
  return createRegularAtomFamily(options, store);
494
495
  }
495
-
496
- // internal/src/get-state/get-from-store.ts
497
496
  function getFromStore(...params) {
498
497
  let token;
499
498
  let store;
@@ -506,7 +505,31 @@ function getFromStore(...params) {
506
505
  store = params[2];
507
506
  const maybeToken = family.type === `molecule_family` ? seekInStore(family, key, store) : store.config.lifespan === `immortal` ? seekInStore(family, key, store) : findInStore(family, key, store);
508
507
  if (!maybeToken) {
509
- throw new NotFoundError(family, key, store);
508
+ store.logger.error(
509
+ `\u2757`,
510
+ family.type,
511
+ family.key,
512
+ `tried to get member`,
513
+ stringifyJson(key),
514
+ `but it was not found in store`,
515
+ store.config.name
516
+ );
517
+ switch (family.type) {
518
+ case `atom_family`:
519
+ case `mutable_atom_family`:
520
+ return store.defaults.get(family.key);
521
+ case `selector_family`:
522
+ case `readonly_selector_family`: {
523
+ if (store.defaults.has(family.key)) {
524
+ return store.defaults.get(family.key);
525
+ }
526
+ const defaultValue = withdraw(family, store).default(key);
527
+ store.defaults.set(family.key, defaultValue);
528
+ return defaultValue;
529
+ }
530
+ case `molecule_family`:
531
+ throw new NotFoundError(family, key, store);
532
+ }
510
533
  }
511
534
  token = maybeToken;
512
535
  }
@@ -720,18 +743,18 @@ var createWritableSelector = (options, family, store) => {
720
743
  const target = newest(store);
721
744
  const subject = new Subject();
722
745
  const covered = /* @__PURE__ */ new Set();
723
- const toolkit = registerSelector(options.key, covered, target);
724
- const { find, get, seek, json } = toolkit;
746
+ const setterToolkit = registerSelector(options.key, covered, target);
747
+ const { find, get, seek, json } = setterToolkit;
725
748
  const getterToolkit = { find, get, seek, json };
726
- const getSelf = (innerTarget = newest(store)) => {
727
- const value = options.get(getterToolkit);
749
+ const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
750
+ const value = getFn(getterToolkit);
728
751
  cacheValue(options.key, value, subject, innerTarget);
729
752
  covered.clear();
730
753
  return value;
731
754
  };
732
755
  const setSelf = (next) => {
733
756
  const innerTarget = newest(store);
734
- const oldValue = getSelf(innerTarget);
757
+ const oldValue = getSelf(options.get, innerTarget);
735
758
  const newValue = become(next)(oldValue);
736
759
  store.logger.info(
737
760
  `\u{1F4DD}`,
@@ -748,7 +771,7 @@ var createWritableSelector = (options, family, store) => {
748
771
  if (isRootStore(innerTarget)) {
749
772
  subject.next({ newValue, oldValue });
750
773
  }
751
- options.set(toolkit, newValue);
774
+ options.set(setterToolkit, newValue);
752
775
  };
753
776
  const mySelector = {
754
777
  ...options,
@@ -885,9 +908,18 @@ function createReadonlySelectorFamily(options, store, internalRoles) {
885
908
  return token;
886
909
  };
887
910
  const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
911
+ internalRoles,
888
912
  subject,
889
913
  install: (s) => createReadonlySelectorFamily(options, s),
890
- internalRoles
914
+ default: (key) => {
915
+ const getFn = options.get(key);
916
+ return getFn({
917
+ get: (token) => getFromStore(token, store),
918
+ find: (token, k) => findInStore(token, k, store),
919
+ seek: (token, k) => seekInStore(token, k, store),
920
+ json: (token) => getJsonToken(token, store)
921
+ });
922
+ }
891
923
  });
892
924
  store.families.set(options.key, readonlySelectorFamily);
893
925
  return familyToken;
@@ -917,9 +949,19 @@ function createWritableSelectorFamily(options, store, internalRoles) {
917
949
  return token;
918
950
  };
919
951
  const selectorFamily = Object.assign(familyFunction, familyToken, {
952
+ internalRoles,
920
953
  subject,
921
954
  install: (s) => createWritableSelectorFamily(options, s),
922
- internalRoles
955
+ default: (key) => {
956
+ const getFn = options.get(key);
957
+ return getFn({
958
+ get: (...params) => getFromStore(...params, store),
959
+ // TODO: make store zero-arg
960
+ find: (token, k) => findInStore(token, k, store),
961
+ seek: (token, k) => seekInStore(token, k, store),
962
+ json: (token) => getJsonToken(token, store)
963
+ });
964
+ }
923
965
  });
924
966
  store.families.set(options.key, selectorFamily);
925
967
  return familyToken;
@@ -1051,9 +1093,6 @@ function seekInStore(token, key, store) {
1051
1093
  break;
1052
1094
  case `molecule_family`:
1053
1095
  state = target.molecules.get(stringifyJson(key));
1054
- if (state) {
1055
- return deposit(state);
1056
- }
1057
1096
  }
1058
1097
  if (state) {
1059
1098
  return deposit(state);
@@ -1089,7 +1128,16 @@ function disposeFromStore(...params) {
1089
1128
  store = params[2];
1090
1129
  const maybeToken = family.type === `molecule_family` ? seekInStore(family, key, store) : store.config.lifespan === `immortal` ? seekInStore(family, key, store) : findInStore(family, key, store);
1091
1130
  if (!maybeToken) {
1092
- throw new NotFoundError(family, key, store);
1131
+ store.logger.error(
1132
+ `\u2757`,
1133
+ family.type,
1134
+ family.key,
1135
+ `tried to dispose of member`,
1136
+ stringifyJson(key),
1137
+ `but it was not found in store`,
1138
+ store.config.name
1139
+ );
1140
+ return;
1093
1141
  }
1094
1142
  token = maybeToken;
1095
1143
  }
@@ -1124,7 +1172,18 @@ function setIntoStore(...params) {
1124
1172
  store = params[3];
1125
1173
  const maybeToken = store.config.lifespan === `ephemeral` ? findInStore(family, key, store) : seekInStore(family, key, store);
1126
1174
  if (!maybeToken) {
1127
- throw new NotFoundError(family, key, store);
1175
+ store.logger.error(
1176
+ `\u2757`,
1177
+ family.type,
1178
+ family.key,
1179
+ `tried to set member`,
1180
+ stringifyJson(key),
1181
+ `to`,
1182
+ value,
1183
+ `but it was not found in store`,
1184
+ store.config.name
1185
+ );
1186
+ return;
1128
1187
  }
1129
1188
  token = maybeToken;
1130
1189
  }
@@ -1609,6 +1668,7 @@ var buildTransaction = (key, params, store, id) => {
1609
1668
  }),
1610
1669
  selectors: new LazyMap(parent.selectors),
1611
1670
  valueMap: new LazyMap(parent.valueMap),
1671
+ defaults: parent.defaults,
1612
1672
  molecules: new LazyMap(parent.molecules),
1613
1673
  moleculeFamilies: new LazyMap(parent.moleculeFamilies),
1614
1674
  moleculeInProgress: parent.moleculeInProgress,
@@ -1711,6 +1771,7 @@ var Store = class {
1711
1771
  parent = null;
1712
1772
  child = null;
1713
1773
  valueMap = /* @__PURE__ */ new Map();
1774
+ defaults = /* @__PURE__ */ new Map();
1714
1775
  atoms = /* @__PURE__ */ new Map();
1715
1776
  selectors = /* @__PURE__ */ new Map();
1716
1777
  readonlySelectors = /* @__PURE__ */ new Map();
package/dist/index.d.ts CHANGED
@@ -287,7 +287,7 @@ declare const LoggerIconDictionary: {
287
287
  readonly "\uD83D\uDC41": "Determining perspective";
288
288
  };
289
289
  type LoggerIcon = keyof typeof LoggerIconDictionary;
290
- type TokenDenomination = `atom` | `continuity` | `molecule_family` | `molecule` | `mutable_atom` | `readonly_selector` | `selector` | `state` | `timeline` | `transaction` | `unknown`;
290
+ type TokenDenomination = `atom_family` | `atom` | `continuity` | `molecule_family` | `molecule` | `mutable_atom_family` | `mutable_atom` | `readonly_selector_family` | `readonly_selector` | `selector_family` | `selector` | `state` | `timeline` | `transaction` | `unknown`;
291
291
  declare const LOG_LEVELS: readonly ["info", "warn", "error"];
292
292
  type LogLevel = (typeof LOG_LEVELS)[number];
293
293
  type LogFn = (icon: LoggerIcon, denomination: TokenDenomination, tokenKey: string, message: string, ...rest: unknown[]) => void;
@@ -1,5 +1,5 @@
1
1
  import * as atom_io from 'atom.io';
2
- import { TransactionToken, TransactionUpdate, TransactionOptions, ActorToolkit, RegularAtomToken, MutableAtomToken, AtomToken, WritableSelectorToken, ReadonlySelectorToken, SelectorToken, WritableToken, MoleculeToken, MoleculeFamily, MoleculeFamilyToken, ReadableToken, TimelineManageable, StateUpdate, TokenType, FamilyMetadata, StateCreation, StateDisposal, MoleculeConstructor, MoleculeCreation, MoleculeDisposal, TimelineUpdate, TimelineOptions, TimelineToken, AtomIOLogger, Logger, RegularAtomFamilyToken, MutableAtomFamilyToken, AtomFamilyToken, ReadonlySelectorFamilyToken, WritableSelectorFamilyToken, SelectorFamilyToken, ReadableFamilyToken, WritableFamilyToken, MutableAtomOptions, MutableAtomFamilyOptions, RegularAtomOptions, RegularAtomFamilyOptions, ReadonlySelectorFamilyOptions, WritableSelectorFamilyOptions, MoleculeKey, KeyedStateUpdate, MoleculeFamilyOptions, MoleculeParams, ReadonlySelectorOptions, WritableSelectorOptions, SetterToolkit, UpdateHandler, TransactionUpdateHandler } from 'atom.io';
2
+ import { TransactionToken, TransactionUpdate, TransactionOptions, ActorToolkit, RegularAtomToken, MutableAtomToken, AtomToken, WritableSelectorToken, ReadonlySelectorToken, SelectorToken, WritableToken, MoleculeConstructor, MoleculeFamily, MoleculeFamilyToken, MoleculeToken, ReadableToken, TimelineManageable, StateUpdate, TokenType, FamilyMetadata, StateCreation, StateDisposal, MoleculeCreation, MoleculeDisposal, TimelineUpdate, TimelineOptions, TimelineToken, AtomIOLogger, Logger, RegularAtomFamilyToken, MutableAtomFamilyToken, AtomFamilyToken, ReadonlySelectorFamilyToken, WritableSelectorFamilyToken, SelectorFamilyToken, ReadableFamilyToken, WritableFamilyToken, MutableAtomOptions, MutableAtomFamilyOptions, RegularAtomOptions, RegularAtomFamilyOptions, ReadonlySelectorFamilyOptions, WritableSelectorFamilyOptions, MoleculeKey, KeyedStateUpdate, MoleculeFamilyOptions, MoleculeParams, ReadonlySelectorOptions, WritableSelectorOptions, SetterToolkit, UpdateHandler, TransactionUpdateHandler } from 'atom.io';
3
3
  import { Canonical, Json, JsonInterface } from 'atom.io/json';
4
4
  import { Join } from 'atom.io/data';
5
5
 
@@ -156,14 +156,11 @@ declare function deposit<T>(state: WritableSelector<T>): WritableSelectorToken<T
156
156
  declare function deposit<T>(state: ReadonlySelector<T>): ReadonlySelectorToken<T>;
157
157
  declare function deposit<T>(state: Selector<T>): SelectorToken<T>;
158
158
  declare function deposit<T>(state: WritableState<T>): WritableToken<T>;
159
- declare function deposit<K extends Canonical, S extends {
160
- [key: string]: any;
161
- }, P extends any[]>(state: Molecule<any>): MoleculeToken<any>;
162
- declare function deposit<K extends Canonical, S extends {
163
- [key: string]: any;
164
- }, P extends any[]>(state: MoleculeFamily<any>): MoleculeFamilyToken<any>;
159
+ declare function deposit<M extends MoleculeConstructor>(state: MoleculeFamily<M>): MoleculeFamilyToken<M>;
160
+ declare function deposit<M extends MoleculeConstructor>(state: Molecule<M>): MoleculeToken<M>;
165
161
  declare function deposit<T extends Func>(state: Transaction<T>): TransactionToken<T>;
166
162
  declare function deposit<T>(state: ReadableState<T>): ReadableToken<T>;
163
+ declare function deposit(state: Molecule<any> | ReadableState<any>): MoleculeToken<any> | ReadableToken<any>;
167
164
 
168
165
  interface Lineage {
169
166
  parent: typeof this | null;
@@ -236,6 +233,7 @@ declare class Store implements Lineage {
236
233
  parent: Store | null;
237
234
  child: Store | null;
238
235
  valueMap: Map<string, any>;
236
+ defaults: Map<string, any>;
239
237
  atoms: Map<string, Atom<any>>;
240
238
  selectors: Map<string, WritableSelector<any>>;
241
239
  readonlySelectors: Map<string, ReadonlySelector<any>>;
@@ -604,15 +602,14 @@ type MutableAtomFamily<T extends Transceiver<any>, J extends Json.Serializable,
604
602
  internalRoles: string[] | undefined;
605
603
  };
606
604
  type AtomFamily<T, K extends Canonical = Canonical> = MutableAtomFamily<T extends Transceiver<any> ? T : never, any, K> | RegularAtomFamily<T, K>;
607
- type WritableSelectorFamily<T, K extends Canonical> = WritableSelectorFamilyToken<T, K> & {
608
- (key: K): WritableSelectorToken<T>;
605
+ type WritableSelectorFamily<T, K extends Canonical> = WritableSelectorFamilyToken<T, K> & ((key: K) => WritableSelectorToken<T>) & {
606
+ default: (key: K) => T;
609
607
  subject: Subject<StateCreation<WritableSelectorToken<T>> | StateDisposal<WritableSelectorToken<T>>>;
610
608
  install: (store: Store) => void;
611
609
  internalRoles: string[] | undefined;
612
610
  };
613
- type ReadonlySelectorFamily<T, K extends Canonical> = ((key: K) => ReadonlySelectorToken<T>) & {
614
- key: string;
615
- type: `readonly_selector_family`;
611
+ type ReadonlySelectorFamily<T, K extends Canonical> = ReadonlySelectorFamilyToken<T, K> & ((key: K) => ReadonlySelectorToken<T>) & {
612
+ default: (key: K) => T;
616
613
  subject: Subject<StateCreation<ReadonlySelectorToken<T>> | StateDisposal<ReadonlySelectorToken<T>>>;
617
614
  install: (store: Store) => void;
618
615
  internalRoles: string[] | undefined;
@@ -1,3 +1,3 @@
1
- export { FamilyTracker, Future, IMPLICIT, LazyMap, Molecule, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMoleculeFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deposit, disposeAtom, disposeFromStore, disposeMolecule, disposeSelector, eldest, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateFamily, getUpdateToken, growMoleculeInStore, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, isAtomDefault, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeMoleculeInStore, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, prettyPrintTokenType, readCachedValue, readOrComputeValue, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw } from '../../dist/chunk-ETCFHO7J.js';
1
+ export { FamilyTracker, Future, IMPLICIT, LazyMap, Molecule, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMoleculeFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deposit, disposeAtom, disposeFromStore, disposeMolecule, disposeSelector, eldest, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateFamily, getUpdateToken, growMoleculeInStore, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, isAtomDefault, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeMoleculeInStore, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, prettyPrintTokenType, readCachedValue, readOrComputeValue, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw } from '../../dist/chunk-JRENM6KL.js';
2
2
  import '../../dist/chunk-IBTHB2PI.js';
3
3
  import '../../dist/chunk-XWL6SNVU.js';
@@ -6,10 +6,18 @@ import type {
6
6
  StateCreation,
7
7
  StateDisposal,
8
8
  } from "atom.io"
9
+ import type { findState } from "atom.io/ephemeral"
10
+ import type { seekState } from "atom.io/immortal"
9
11
  import type { Canonical } from "atom.io/json"
10
12
  import { stringifyJson } from "atom.io/json"
11
13
 
12
- import type { ReadonlySelectorFamily } from ".."
14
+ import {
15
+ findInStore,
16
+ getFromStore,
17
+ getJsonToken,
18
+ type ReadonlySelectorFamily,
19
+ seekInStore,
20
+ } from ".."
13
21
  import { newest } from "../lineage"
14
22
  import { createReadonlySelector } from "../selector"
15
23
  import type { Store } from "../store"
@@ -53,9 +61,18 @@ export function createReadonlySelectorFamily<T, K extends Canonical>(
53
61
  }
54
62
 
55
63
  const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
64
+ internalRoles,
56
65
  subject,
57
66
  install: (s: Store) => createReadonlySelectorFamily(options, s),
58
- internalRoles,
67
+ default: (key: K) => {
68
+ const getFn = options.get(key)
69
+ return getFn({
70
+ get: (token) => getFromStore(token, store),
71
+ find: ((token, k) => findInStore(token, k, store)) as typeof findState,
72
+ seek: ((token, k) => seekInStore(token, k, store)) as typeof seekState,
73
+ json: (token) => getJsonToken(token, store),
74
+ })
75
+ },
59
76
  }) satisfies ReadonlySelectorFamily<T, K>
60
77
 
61
78
  store.families.set(options.key, readonlySelectorFamily)
@@ -61,5 +61,6 @@ export function createRegularAtomFamily<T, K extends Canonical>(
61
61
  }) satisfies RegularAtomFamily<T, K>
62
62
 
63
63
  store.families.set(options.key, atomFamily)
64
+ store.defaults.set(options.key, options.default)
64
65
  return familyToken
65
66
  }
@@ -6,10 +6,18 @@ import type {
6
6
  WritableSelectorFamilyToken,
7
7
  WritableSelectorToken,
8
8
  } from "atom.io"
9
+ import type { findState } from "atom.io/ephemeral"
10
+ import type { seekState } from "atom.io/immortal"
9
11
  import type { Canonical } from "atom.io/json"
10
12
  import { stringifyJson } from "atom.io/json"
11
13
 
12
- import type { WritableSelectorFamily } from ".."
14
+ import {
15
+ findInStore,
16
+ getFromStore,
17
+ getJsonToken,
18
+ seekInStore,
19
+ type WritableSelectorFamily,
20
+ } from ".."
13
21
  import { newest } from "../lineage"
14
22
  import { createWritableSelector } from "../selector"
15
23
  import type { Store } from "../store"
@@ -54,9 +62,18 @@ export function createWritableSelectorFamily<T, K extends Canonical>(
54
62
  }
55
63
 
56
64
  const selectorFamily = Object.assign(familyFunction, familyToken, {
65
+ internalRoles,
57
66
  subject,
58
67
  install: (s: Store) => createWritableSelectorFamily(options, s),
59
- internalRoles,
68
+ default: (key: K) => {
69
+ const getFn = options.get(key)
70
+ return getFn({
71
+ get: (...params: [any]) => getFromStore(...params, store), // TODO: make store zero-arg
72
+ find: ((token, k) => findInStore(token, k, store)) as typeof findState,
73
+ seek: ((token, k) => seekInStore(token, k, store)) as typeof seekState,
74
+ json: (token) => getJsonToken(token, store),
75
+ })
76
+ },
60
77
  }) satisfies WritableSelectorFamily<T, K>
61
78
 
62
79
  store.families.set(options.key, selectorFamily)
@@ -6,7 +6,7 @@ import type {
6
6
  ReadableFamilyToken,
7
7
  ReadableToken,
8
8
  } from "atom.io"
9
- import type { Canonical } from "atom.io/json"
9
+ import { type Canonical, stringifyJson } from "atom.io/json"
10
10
 
11
11
  import { disposeAtom } from "../atom"
12
12
  import { disposeMolecule } from "../molecule/dispose-molecule"
@@ -55,7 +55,16 @@ export function disposeFromStore(
55
55
  ? seekInStore(family, key, store)
56
56
  : findInStore(family, key, store)
57
57
  if (!maybeToken) {
58
- throw new NotFoundError(family, key, store)
58
+ store.logger.error(
59
+ `❗`,
60
+ family.type,
61
+ family.key,
62
+ `tried to dispose of member`,
63
+ stringifyJson(key),
64
+ `but it was not found in store`,
65
+ store.config.name,
66
+ )
67
+ return
59
68
  }
60
69
  token = maybeToken
61
70
  }
@@ -109,9 +109,6 @@ export function seekInStore(
109
109
  break
110
110
  case `molecule_family`:
111
111
  state = target.molecules.get(stringifyJson(key))
112
- if (state) {
113
- return deposit(state)
114
- }
115
112
  }
116
113
  if (state) {
117
114
  return deposit(state)
@@ -6,7 +6,7 @@ import type {
6
6
  ReadableFamilyToken,
7
7
  ReadableToken,
8
8
  } from "atom.io"
9
- import type { Canonical } from "atom.io/json"
9
+ import { type Canonical, stringifyJson } from "atom.io/json"
10
10
 
11
11
  import { findInStore, seekInStore } from "../families"
12
12
  import { NotFoundError } from "../not-found-error"
@@ -56,7 +56,31 @@ export function getFromStore<T>(
56
56
  ? seekInStore(family, key, store)
57
57
  : findInStore(family, key, store)
58
58
  if (!maybeToken) {
59
- throw new NotFoundError(family, key, store)
59
+ store.logger.error(
60
+ `❗`,
61
+ family.type,
62
+ family.key,
63
+ `tried to get member`,
64
+ stringifyJson(key),
65
+ `but it was not found in store`,
66
+ store.config.name,
67
+ )
68
+ switch (family.type) {
69
+ case `atom_family`:
70
+ case `mutable_atom_family`:
71
+ return store.defaults.get(family.key)
72
+ case `selector_family`:
73
+ case `readonly_selector_family`: {
74
+ if (store.defaults.has(family.key)) {
75
+ return store.defaults.get(family.key)
76
+ }
77
+ const defaultValue = withdraw(family, store).default(key)
78
+ store.defaults.set(family.key, defaultValue)
79
+ return defaultValue
80
+ }
81
+ case `molecule_family`:
82
+ throw new NotFoundError(family, key, store)
83
+ }
60
84
  }
61
85
  token = maybeToken
62
86
  }
@@ -10,7 +10,7 @@ export const readOrComputeValue = <T>(
10
10
  target.logger.info(`📖`, state.type, state.key, `reading cached value`)
11
11
  return readCachedValue(state, target)
12
12
  }
13
- if (state.type !== `atom` && state.type !== `mutable_atom`) {
13
+ if (state.type === `selector` || state.type === `readonly_selector`) {
14
14
  target.logger.info(`🧮`, state.type, state.key, `computing value`)
15
15
  return state.get()
16
16
  }
@@ -3,6 +3,7 @@ import type {
3
3
  FamilyMetadata,
4
4
  MutableAtomFamilyToken,
5
5
  MutableAtomToken,
6
+ ReadonlySelectorFamilyToken,
6
7
  ReadonlySelectorToken,
7
8
  RegularAtomFamilyToken,
8
9
  RegularAtomToken,
@@ -113,8 +114,9 @@ export type AtomFamily<T, K extends Canonical = Canonical> =
113
114
  // biome-ignore format: intersection
114
115
  export type WritableSelectorFamily<T, K extends Canonical> =
115
116
  & WritableSelectorFamilyToken<T, K>
117
+ & ((key: K) => WritableSelectorToken<T>)
116
118
  & {
117
- (key: K): WritableSelectorToken<T>
119
+ default: (key: K) => T,
118
120
  subject: Subject<StateCreation<WritableSelectorToken<T>> | StateDisposal<WritableSelectorToken<T>>>
119
121
  install: (store: Store) => void
120
122
  internalRoles : string[] | undefined
@@ -122,10 +124,10 @@ export type WritableSelectorFamily<T, K extends Canonical> =
122
124
 
123
125
  // biome-ignore format: intersection
124
126
  export type ReadonlySelectorFamily<T, K extends Canonical> =
127
+ & ReadonlySelectorFamilyToken<T, K>
125
128
  & ((key: K) => ReadonlySelectorToken<T>)
126
129
  & {
127
- key: string
128
- type: `readonly_selector_family`
130
+ default: (key: K) => T,
129
131
  subject: Subject<StateCreation<ReadonlySelectorToken<T>> | StateDisposal<ReadonlySelectorToken<T>>>
130
132
  install: (store: Store) => void
131
133
  internalRoles : string[] | undefined
@@ -22,12 +22,12 @@ export const createWritableSelector = <T>(
22
22
  const target = newest(store)
23
23
  const subject = new Subject<{ newValue: T; oldValue: T }>()
24
24
  const covered = new Set<string>()
25
- const toolkit = registerSelector(options.key, covered, target)
26
- const { find, get, seek, json } = toolkit
25
+ const setterToolkit = registerSelector(options.key, covered, target)
26
+ const { find, get, seek, json } = setterToolkit
27
27
  const getterToolkit = { find, get, seek, json }
28
28
 
29
- const getSelf = (innerTarget = newest(store)): T => {
30
- const value = options.get(getterToolkit)
29
+ const getSelf = (getFn = options.get, innerTarget = newest(store)): T => {
30
+ const value = getFn(getterToolkit)
31
31
  cacheValue(options.key, value, subject, innerTarget)
32
32
  covered.clear()
33
33
  return value
@@ -35,7 +35,7 @@ export const createWritableSelector = <T>(
35
35
 
36
36
  const setSelf = (next: T | ((oldValue: T) => T)): void => {
37
37
  const innerTarget = newest(store)
38
- const oldValue = getSelf(innerTarget)
38
+ const oldValue = getSelf(options.get, innerTarget)
39
39
  const newValue = become(next)(oldValue)
40
40
  store.logger.info(
41
41
  `📝`,
@@ -52,7 +52,7 @@ export const createWritableSelector = <T>(
52
52
  if (isRootStore(innerTarget)) {
53
53
  subject.next({ newValue, oldValue })
54
54
  }
55
- options.set(toolkit, newValue)
55
+ options.set(setterToolkit, newValue)
56
56
  }
57
57
  const mySelector: WritableSelector<T> = {
58
58
  ...options,
@@ -1,5 +1,5 @@
1
1
  import type { WritableFamilyToken, WritableToken } from "atom.io"
2
- import type { Canonical } from "atom.io/json"
2
+ import { type Canonical, stringifyJson } from "atom.io/json"
3
3
 
4
4
  import { findInStore, seekInStore } from "../families"
5
5
  import { NotFoundError } from "../not-found-error"
@@ -52,7 +52,18 @@ export function setIntoStore<T, New extends T>(
52
52
  ? findInStore(family, key, store)
53
53
  : seekInStore(family, key, store)
54
54
  if (!maybeToken) {
55
- throw new NotFoundError(family, key, store)
55
+ store.logger.error(
56
+ `❗`,
57
+ family.type,
58
+ family.key,
59
+ `tried to set member`,
60
+ stringifyJson(key),
61
+ `to`,
62
+ value,
63
+ `but it was not found in store`,
64
+ store.config.name,
65
+ )
66
+ return
56
67
  }
57
68
  token = maybeToken
58
69
  }
@@ -1,5 +1,6 @@
1
1
  import type {
2
2
  AtomToken,
3
+ MoleculeConstructor,
3
4
  MoleculeFamily,
4
5
  MoleculeFamilyToken,
5
6
  MoleculeToken,
@@ -38,20 +39,20 @@ export function deposit<T>(state: WritableSelector<T>): WritableSelectorToken<T>
38
39
  export function deposit<T>(state: ReadonlySelector<T>): ReadonlySelectorToken<T>
39
40
  export function deposit<T>(state: Selector<T>): SelectorToken<T>
40
41
  export function deposit<T>(state: WritableState<T>): WritableToken<T>
41
- export function deposit<
42
- K extends Canonical,
43
- S extends { [key: string]: any },
44
- P extends any[],
45
- >(state: Molecule<any>): MoleculeToken<any>
46
- export function deposit<
47
- K extends Canonical,
48
- S extends { [key: string]: any },
49
- P extends any[],
50
- >(state: MoleculeFamily<any>): MoleculeFamilyToken<any>
42
+ export function deposit<M extends MoleculeConstructor>(
43
+ state: MoleculeFamily<M>,
44
+ ): MoleculeFamilyToken<M>
45
+ export function deposit<M extends MoleculeConstructor>(
46
+ state: Molecule<M>,
47
+ ): MoleculeToken<M>
51
48
  export function deposit<T extends Func>(
52
49
  state: Transaction<T>,
53
50
  ): TransactionToken<T>
54
51
  export function deposit<T>(state: ReadableState<T>): ReadableToken<T>
52
+ export function deposit(
53
+ state: Molecule<any> | ReadableState<any>,
54
+ ): MoleculeToken<any> | ReadableToken<any>
55
+
55
56
  export function deposit<T>(
56
57
  state:
57
58
  | Molecule<any>
@@ -42,6 +42,7 @@ export class Store implements Lineage {
42
42
  public child: Store | null = null
43
43
 
44
44
  public valueMap = new Map<string, any>()
45
+ public defaults = new Map<string, any>()
45
46
 
46
47
  public atoms = new Map<string, Atom<any>>()
47
48
  public selectors = new Map<string, WritableSelector<any>>()
@@ -48,6 +48,7 @@ export const buildTransaction = (
48
48
  }),
49
49
  selectors: new LazyMap(parent.selectors),
50
50
  valueMap: new LazyMap(parent.valueMap),
51
+ defaults: parent.defaults,
51
52
  molecules: new LazyMap(parent.molecules),
52
53
  moleculeFamilies: new LazyMap(parent.moleculeFamilies),
53
54
  moleculeInProgress: parent.moleculeInProgress,
@@ -1,6 +1,6 @@
1
1
  import { stringifyJson, parseJson } from '../../dist/chunk-AK23DRMD.js';
2
2
  export { parseJson, stringifyJson } from '../../dist/chunk-AK23DRMD.js';
3
- import { createWritableSelectorFamily } from '../../dist/chunk-ETCFHO7J.js';
3
+ import { createWritableSelectorFamily } from '../../dist/chunk-JRENM6KL.js';
4
4
  import '../../dist/chunk-IBTHB2PI.js';
5
5
  import '../../dist/chunk-XWL6SNVU.js';
6
6
  import { createStandaloneSelector, IMPLICIT, growMoleculeInStore, initFamilyMemberInStore, withdraw, seekInStore } from 'atom.io/internal';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom.io",
3
- "version": "0.27.3",
3
+ "version": "0.27.4",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -67,7 +67,7 @@
67
67
  "drizzle-kit": "0.24.0",
68
68
  "drizzle-orm": "0.33.0",
69
69
  "eslint": "9.9.0",
70
- "framer-motion": "11.3.24",
70
+ "framer-motion": "11.3.28",
71
71
  "happy-dom": "14.12.3",
72
72
  "http-proxy": "1.18.1",
73
73
  "npmlog": "7.0.1",
@@ -75,14 +75,14 @@
75
75
  "preact": "10.23.2",
76
76
  "react": "18.3.1",
77
77
  "react-dom": "18.3.1",
78
- "react-router-dom": "6.26.0",
78
+ "react-router-dom": "6.26.1",
79
79
  "socket.io": "4.7.5",
80
80
  "socket.io-client": "4.7.5",
81
81
  "tmp": "0.2.3",
82
82
  "tsup": "8.2.4",
83
83
  "tsx": "4.17.0",
84
84
  "typescript": "5.5.4",
85
- "vite": "5.4.0",
85
+ "vite": "5.4.1",
86
86
  "vite-tsconfig-paths": "5.0.1",
87
87
  "vitest": "2.0.5"
88
88
  },
package/src/logger.ts CHANGED
@@ -52,12 +52,16 @@ const LoggerIconDictionary = {
52
52
  } as const
53
53
  export type LoggerIcon = keyof typeof LoggerIconDictionary
54
54
  export type TokenDenomination =
55
+ | `atom_family`
55
56
  | `atom`
56
57
  | `continuity`
57
58
  | `molecule_family`
58
59
  | `molecule`
60
+ | `mutable_atom_family`
59
61
  | `mutable_atom`
62
+ | `readonly_selector_family`
60
63
  | `readonly_selector`
64
+ | `selector_family`
61
65
  | `selector`
62
66
  | `state`
63
67
  | `timeline`