atom.io 0.27.5 → 0.28.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.
- package/data/dist/index.d.ts +31 -29
- package/data/dist/index.js +16 -17
- package/data/src/join.ts +17 -19
- package/dist/{chunk-6ABWLAGY.js → chunk-BX3MTH2Z.js} +320 -249
- package/dist/chunk-D52JNVER.js +721 -0
- package/dist/chunk-EUVKUTW3.js +89 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/internal/dist/index.d.ts +72 -36
- package/internal/dist/index.js +1 -1
- package/internal/src/atom/dispose-atom.ts +2 -9
- package/internal/src/families/dispose-from-store.ts +35 -18
- package/internal/src/families/find-in-store.ts +17 -7
- package/internal/src/get-state/get-from-store.ts +41 -32
- package/internal/src/ingest-updates/ingest-creation-disposal.ts +10 -1
- package/internal/src/molecule/dispose-molecule.ts +6 -17
- package/internal/src/pretty-print.ts +1 -16
- package/internal/src/selector/dispose-selector.ts +2 -9
- package/internal/src/set-state/set-into-store.ts +17 -19
- package/internal/src/store/circular-buffer.ts +34 -0
- package/internal/src/store/counterfeit.ts +109 -0
- package/internal/src/store/deposit.ts +14 -0
- package/internal/src/store/index.ts +1 -0
- package/internal/src/store/store.ts +3 -0
- package/internal/src/store/withdraw.ts +15 -10
- package/internal/src/transaction/build-transaction.ts +1 -0
- package/introspection/dist/index.d.ts +84 -4
- package/introspection/dist/index.js +1 -392
- package/introspection/src/attach-introspection-states.ts +7 -4
- package/introspection/src/attach-type-selectors.ts +26 -0
- package/introspection/src/differ.ts +167 -0
- package/introspection/src/index.ts +2 -0
- package/introspection/src/refinery.ts +100 -0
- package/json/dist/index.d.ts +31 -30
- package/json/dist/index.js +2 -77
- package/json/src/entries.ts +6 -0
- package/json/src/index.ts +47 -6
- package/package.json +17 -8
- package/react-devtools/dist/index.d.ts +1 -91
- package/react-devtools/dist/index.js +285 -414
- package/react-devtools/src/AtomIODevtools.tsx +2 -2
- package/react-devtools/src/StateEditor.tsx +20 -12
- package/react-devtools/src/StateIndex.tsx +8 -26
- package/react-devtools/src/TimelineIndex.tsx +3 -3
- package/react-devtools/src/TransactionIndex.tsx +6 -6
- package/react-devtools/src/Updates.tsx +1 -4
- package/react-devtools/src/index.ts +0 -71
- package/react-devtools/src/store.ts +51 -0
- package/realtime/dist/index.d.ts +7 -7
- package/realtime/dist/index.js +18 -22
- package/realtime/src/realtime-continuity.ts +27 -35
- package/realtime-client/dist/index.js +24 -10
- package/realtime-client/src/realtime-client-stores/client-main-store.ts +6 -6
- package/realtime-client/src/sync-continuity.ts +28 -6
- package/realtime-server/dist/index.js +41 -5
- package/realtime-server/src/realtime-continuity-synchronizer.ts +42 -78
- package/realtime-testing/dist/index.d.ts +2 -0
- package/realtime-testing/dist/index.js +50 -8
- package/realtime-testing/src/setup-realtime-test.tsx +59 -9
- package/src/silo.ts +7 -3
- package/web/dist/index.d.ts +9 -0
- package/{dist/chunk-H6EDLPKH.js → web/dist/index.js} +5 -4
- package/web/package.json +13 -0
- package/web/src/index.ts +1 -0
- package/web/src/persist-sync.ts +25 -0
- package/dist/chunk-AK23DRMD.js +0 -21
- package/dist/chunk-IW6WYRS7.js +0 -140
|
@@ -67,6 +67,37 @@ function eldest(scion) {
|
|
|
67
67
|
}
|
|
68
68
|
return scion;
|
|
69
69
|
}
|
|
70
|
+
var FAMILY_MEMBER_TOKEN_TYPES = {
|
|
71
|
+
atom_family: `atom`,
|
|
72
|
+
mutable_atom_family: `mutable_atom`,
|
|
73
|
+
selector_family: `selector`,
|
|
74
|
+
readonly_selector_family: `readonly_selector`,
|
|
75
|
+
molecule_family: `molecule`
|
|
76
|
+
};
|
|
77
|
+
function counterfeit(token, key) {
|
|
78
|
+
const subKey = stringifyJson(key);
|
|
79
|
+
const fullKey = `${token.key}(${subKey})`;
|
|
80
|
+
const type = FAMILY_MEMBER_TOKEN_TYPES[token.type];
|
|
81
|
+
const stateToken = {
|
|
82
|
+
key: fullKey,
|
|
83
|
+
type
|
|
84
|
+
};
|
|
85
|
+
if (type === `molecule`) {
|
|
86
|
+
Object.assign(stateToken, {
|
|
87
|
+
key,
|
|
88
|
+
family: token
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
Object.assign(stateToken, {
|
|
92
|
+
family: {
|
|
93
|
+
key: token.key,
|
|
94
|
+
subKey
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
Object.assign(stateToken, { counterfeit: true });
|
|
99
|
+
return stateToken;
|
|
100
|
+
}
|
|
70
101
|
|
|
71
102
|
// internal/src/store/deposit.ts
|
|
72
103
|
function deposit(state) {
|
|
@@ -145,22 +176,7 @@ var abortTransaction = (store) => {
|
|
|
145
176
|
// internal/src/pretty-print.ts
|
|
146
177
|
var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
|
|
147
178
|
function prettyPrintTokenType(token) {
|
|
148
|
-
|
|
149
|
-
case `atom_family`:
|
|
150
|
-
return `Atom Family`;
|
|
151
|
-
case `molecule_family`:
|
|
152
|
-
return `Molecule Family`;
|
|
153
|
-
case `mutable_atom_family`:
|
|
154
|
-
return `Mutable Atom Family`;
|
|
155
|
-
case `readonly_selector`:
|
|
156
|
-
return `Readonly Selector`;
|
|
157
|
-
case `readonly_selector_family`:
|
|
158
|
-
return `Readonly Selector Family`;
|
|
159
|
-
case `selector_family`:
|
|
160
|
-
return `Selector Family`;
|
|
161
|
-
default:
|
|
162
|
-
return capitalize(token.type);
|
|
163
|
-
}
|
|
179
|
+
return token.type.split(`_`).map(capitalize).join(` `);
|
|
164
180
|
}
|
|
165
181
|
|
|
166
182
|
// internal/src/not-found-error.ts
|
|
@@ -490,6 +506,8 @@ function createAtomFamily(store, options) {
|
|
|
490
506
|
}
|
|
491
507
|
return createRegularAtomFamily(store, options);
|
|
492
508
|
}
|
|
509
|
+
|
|
510
|
+
// internal/src/get-state/get-from-store.ts
|
|
493
511
|
function getFromStore(store, ...params) {
|
|
494
512
|
let token;
|
|
495
513
|
if (params.length === 1) {
|
|
@@ -497,35 +515,47 @@ function getFromStore(store, ...params) {
|
|
|
497
515
|
} else {
|
|
498
516
|
const family = params[0];
|
|
499
517
|
const key = params[1];
|
|
500
|
-
|
|
501
|
-
if (
|
|
502
|
-
store
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
518
|
+
let maybeToken;
|
|
519
|
+
if (family.type === `molecule_family`) {
|
|
520
|
+
maybeToken = seekInStore(store, family, key) ?? counterfeit(family, key);
|
|
521
|
+
} else {
|
|
522
|
+
maybeToken = findInStore(store, family, key);
|
|
523
|
+
}
|
|
524
|
+
token = maybeToken;
|
|
525
|
+
}
|
|
526
|
+
if (`counterfeit` in token && `family` in token) {
|
|
527
|
+
const family = token.type === `molecule` ? withdraw(token.family, store) : (
|
|
528
|
+
// biome-ignore lint/style/noNonNullAssertion: family must be present
|
|
529
|
+
store.families.get(token.family.key)
|
|
530
|
+
);
|
|
531
|
+
const subKey = token.type === `molecule` ? token.key : token.family.subKey;
|
|
532
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
533
|
+
(item) => item?.key === token.key
|
|
534
|
+
);
|
|
535
|
+
store.logger.error(
|
|
536
|
+
`\u274C`,
|
|
537
|
+
token.type,
|
|
538
|
+
token.key,
|
|
539
|
+
`could not be retrieved because it was not found in the store "${store.config.name}".`,
|
|
540
|
+
disposal ? `This state was previously disposed:
|
|
541
|
+
${disposal.trace}` : `No previous disposal trace was found.`
|
|
542
|
+
);
|
|
543
|
+
switch (family.type) {
|
|
544
|
+
case `atom_family`:
|
|
545
|
+
case `mutable_atom_family`:
|
|
546
|
+
return store.defaults.get(family.key);
|
|
547
|
+
case `selector_family`:
|
|
548
|
+
case `readonly_selector_family`: {
|
|
549
|
+
if (store.defaults.has(family.key)) {
|
|
550
|
+
return store.defaults.get(token.family.key);
|
|
523
551
|
}
|
|
524
|
-
|
|
525
|
-
|
|
552
|
+
const defaultValue = withdraw(family, store).default(subKey);
|
|
553
|
+
store.defaults.set(family.key, defaultValue);
|
|
554
|
+
return defaultValue;
|
|
526
555
|
}
|
|
556
|
+
case `molecule_family`:
|
|
557
|
+
throw new NotFoundError(family, subKey, store);
|
|
527
558
|
}
|
|
528
|
-
token = maybeToken;
|
|
529
559
|
}
|
|
530
560
|
switch (token.type) {
|
|
531
561
|
case `atom`:
|
|
@@ -806,15 +836,8 @@ function createStandaloneSelector(store, options) {
|
|
|
806
836
|
function disposeSelector(selectorToken, store) {
|
|
807
837
|
const target = newest(store);
|
|
808
838
|
const { key } = selectorToken;
|
|
809
|
-
const selector =
|
|
810
|
-
if (!selector) {
|
|
811
|
-
store.logger.info(
|
|
812
|
-
`\u274C`,
|
|
813
|
-
`selector`,
|
|
814
|
-
key,
|
|
815
|
-
`Tried to dispose selector, but it does not exist in the store.`
|
|
816
|
-
);
|
|
817
|
-
} else if (!selector.family) {
|
|
839
|
+
const selector = withdraw(selectorToken, target);
|
|
840
|
+
if (!selector.family) {
|
|
818
841
|
store.logger.error(
|
|
819
842
|
`\u274C`,
|
|
820
843
|
`selector`,
|
|
@@ -992,21 +1015,12 @@ function createSelectorFamily(store, options) {
|
|
|
992
1015
|
// internal/src/molecule/dispose-molecule.ts
|
|
993
1016
|
function disposeMolecule(token, store) {
|
|
994
1017
|
let molecule;
|
|
995
|
-
|
|
996
|
-
molecule = withdraw(token, store);
|
|
997
|
-
} catch (thrown) {
|
|
998
|
-
if (thrown instanceof Error) {
|
|
999
|
-
store.logger.error(
|
|
1000
|
-
`\u{1F41E}`,
|
|
1001
|
-
`molecule`,
|
|
1002
|
-
JSON.stringify(token.key),
|
|
1003
|
-
`Failed to dispose molecule, because it was not found in the store.`,
|
|
1004
|
-
thrown.message
|
|
1005
|
-
);
|
|
1006
|
-
}
|
|
1007
|
-
return;
|
|
1008
|
-
}
|
|
1018
|
+
molecule = withdraw(token, store);
|
|
1009
1019
|
const { family } = token;
|
|
1020
|
+
for (const join of molecule.joins.values()) {
|
|
1021
|
+
join.relations.delete(molecule.key);
|
|
1022
|
+
join.molecules.delete(molecule.stringKey);
|
|
1023
|
+
}
|
|
1010
1024
|
const context = [];
|
|
1011
1025
|
for (const above of molecule.above.values()) {
|
|
1012
1026
|
context.push(deposit(above));
|
|
@@ -1050,183 +1064,11 @@ function disposeMolecule(token, store) {
|
|
|
1050
1064
|
}
|
|
1051
1065
|
store.molecules.delete(molecule.stringKey);
|
|
1052
1066
|
}
|
|
1053
|
-
for (const join of molecule.joins.values()) {
|
|
1054
|
-
join.molecules.delete(molecule.stringKey);
|
|
1055
|
-
}
|
|
1056
1067
|
for (const parent of molecule.above.values()) {
|
|
1057
1068
|
parent.below.delete(molecule.stringKey);
|
|
1058
1069
|
}
|
|
1059
1070
|
}
|
|
1060
1071
|
|
|
1061
|
-
// internal/src/families/init-family-member.ts
|
|
1062
|
-
function initFamilyMemberInStore(store, token, key) {
|
|
1063
|
-
const familyKey = token.key;
|
|
1064
|
-
const family = store.families.get(familyKey);
|
|
1065
|
-
if (family === void 0) {
|
|
1066
|
-
throw new NotFoundError(token, store);
|
|
1067
|
-
}
|
|
1068
|
-
const state = family(key);
|
|
1069
|
-
const target = newest(store);
|
|
1070
|
-
if (state.family && target.moleculeInProgress === null) {
|
|
1071
|
-
if (isRootStore(target)) {
|
|
1072
|
-
switch (state.type) {
|
|
1073
|
-
case `atom`:
|
|
1074
|
-
case `mutable_atom`:
|
|
1075
|
-
store.on.atomCreation.next(state);
|
|
1076
|
-
break;
|
|
1077
|
-
case `selector`:
|
|
1078
|
-
case `readonly_selector`:
|
|
1079
|
-
store.on.selectorCreation.next(state);
|
|
1080
|
-
break;
|
|
1081
|
-
}
|
|
1082
|
-
} else if (isChildStore(target) && target.on.transactionApplying.state === null) {
|
|
1083
|
-
target.transactionMeta.update.updates.push({
|
|
1084
|
-
type: `state_creation`,
|
|
1085
|
-
token: state
|
|
1086
|
-
});
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
return state;
|
|
1090
|
-
}
|
|
1091
|
-
function seekInStore(store, token, key) {
|
|
1092
|
-
const subKey = stringifyJson(key);
|
|
1093
|
-
const fullKey = `${token.key}(${subKey})`;
|
|
1094
|
-
const target = newest(store);
|
|
1095
|
-
let state;
|
|
1096
|
-
switch (token.type) {
|
|
1097
|
-
case `atom_family`:
|
|
1098
|
-
case `mutable_atom_family`:
|
|
1099
|
-
state = target.atoms.get(fullKey);
|
|
1100
|
-
break;
|
|
1101
|
-
case `selector_family`:
|
|
1102
|
-
state = target.selectors.get(fullKey);
|
|
1103
|
-
break;
|
|
1104
|
-
case `readonly_selector_family`:
|
|
1105
|
-
state = target.readonlySelectors.get(fullKey);
|
|
1106
|
-
break;
|
|
1107
|
-
case `molecule_family`:
|
|
1108
|
-
state = target.molecules.get(stringifyJson(key));
|
|
1109
|
-
}
|
|
1110
|
-
if (state) {
|
|
1111
|
-
return deposit(state);
|
|
1112
|
-
}
|
|
1113
|
-
return state;
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
// internal/src/families/find-in-store.ts
|
|
1117
|
-
function findInStore(store, token, key) {
|
|
1118
|
-
if (store.config.lifespan === `immortal`) {
|
|
1119
|
-
throw new Error(
|
|
1120
|
-
`Do not use \`find\` or \`findState\` in an immortal store. Prefer \`seek\` or \`seekState\`.`
|
|
1121
|
-
);
|
|
1122
|
-
}
|
|
1123
|
-
let state = seekInStore(store, token, key);
|
|
1124
|
-
if (state) {
|
|
1125
|
-
return state;
|
|
1126
|
-
}
|
|
1127
|
-
state = initFamilyMemberInStore(store, token, key);
|
|
1128
|
-
return state;
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
// internal/src/families/dispose-from-store.ts
|
|
1132
|
-
function disposeFromStore(store, ...params) {
|
|
1133
|
-
let token;
|
|
1134
|
-
if (params.length === 1) {
|
|
1135
|
-
token = params[0];
|
|
1136
|
-
} else {
|
|
1137
|
-
const family = params[0];
|
|
1138
|
-
const key = params[1];
|
|
1139
|
-
const maybeToken = family.type === `molecule_family` ? seekInStore(store, family, key) : store.config.lifespan === `immortal` ? seekInStore(store, family, key) : findInStore(store, family, key);
|
|
1140
|
-
if (!maybeToken) {
|
|
1141
|
-
store.logger.error(
|
|
1142
|
-
`\u2757`,
|
|
1143
|
-
family.type,
|
|
1144
|
-
family.key,
|
|
1145
|
-
`tried to dispose of member`,
|
|
1146
|
-
stringifyJson(key),
|
|
1147
|
-
`but it was not found in store`,
|
|
1148
|
-
store.config.name
|
|
1149
|
-
);
|
|
1150
|
-
return;
|
|
1151
|
-
}
|
|
1152
|
-
token = maybeToken;
|
|
1153
|
-
}
|
|
1154
|
-
switch (token.type) {
|
|
1155
|
-
case `atom`:
|
|
1156
|
-
case `mutable_atom`:
|
|
1157
|
-
disposeAtom(token, store);
|
|
1158
|
-
break;
|
|
1159
|
-
case `selector`:
|
|
1160
|
-
case `readonly_selector`:
|
|
1161
|
-
disposeSelector(token, store);
|
|
1162
|
-
break;
|
|
1163
|
-
case `molecule`:
|
|
1164
|
-
disposeMolecule(token, store);
|
|
1165
|
-
break;
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
// internal/src/set-state/set-into-store.ts
|
|
1170
|
-
function setIntoStore(store, ...params) {
|
|
1171
|
-
let token;
|
|
1172
|
-
let value;
|
|
1173
|
-
if (params.length === 2) {
|
|
1174
|
-
token = params[0];
|
|
1175
|
-
value = params[1];
|
|
1176
|
-
} else {
|
|
1177
|
-
const family = params[0];
|
|
1178
|
-
const key = params[1];
|
|
1179
|
-
value = params[2];
|
|
1180
|
-
const maybeToken = store.config.lifespan === `ephemeral` ? findInStore(store, family, key) : seekInStore(store, family, key);
|
|
1181
|
-
if (!maybeToken) {
|
|
1182
|
-
store.logger.error(
|
|
1183
|
-
`\u2757`,
|
|
1184
|
-
family.type,
|
|
1185
|
-
family.key,
|
|
1186
|
-
`tried to set member`,
|
|
1187
|
-
stringifyJson(key),
|
|
1188
|
-
`to`,
|
|
1189
|
-
value,
|
|
1190
|
-
`but it was not found in store`,
|
|
1191
|
-
store.config.name
|
|
1192
|
-
);
|
|
1193
|
-
return;
|
|
1194
|
-
}
|
|
1195
|
-
token = maybeToken;
|
|
1196
|
-
}
|
|
1197
|
-
const rejectionTime = openOperation(token, store);
|
|
1198
|
-
if (rejectionTime) {
|
|
1199
|
-
const unsubscribe = store.on.operationClose.subscribe(
|
|
1200
|
-
`waiting to set "${token.key}" at T-${rejectionTime}`,
|
|
1201
|
-
() => {
|
|
1202
|
-
unsubscribe();
|
|
1203
|
-
store.logger.info(
|
|
1204
|
-
`\u{1F7E2}`,
|
|
1205
|
-
token.type,
|
|
1206
|
-
token.key,
|
|
1207
|
-
`resuming deferred setState from T-${rejectionTime}`
|
|
1208
|
-
);
|
|
1209
|
-
setIntoStore(store, token, value);
|
|
1210
|
-
}
|
|
1211
|
-
);
|
|
1212
|
-
return;
|
|
1213
|
-
}
|
|
1214
|
-
const state = withdraw(token, store);
|
|
1215
|
-
setAtomOrSelector(state, value, store);
|
|
1216
|
-
closeOperation(store);
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
// internal/src/ingest-updates/ingest-atom-update.ts
|
|
1220
|
-
function ingestAtomUpdate(applying, atomUpdate, store) {
|
|
1221
|
-
const { key, newValue, oldValue } = atomUpdate;
|
|
1222
|
-
const value = applying === `newValue` ? newValue : oldValue;
|
|
1223
|
-
const token = { key, type: `atom` };
|
|
1224
|
-
if (atomUpdate.family) {
|
|
1225
|
-
Object.assign(token, { family: atomUpdate.family });
|
|
1226
|
-
}
|
|
1227
|
-
setIntoStore(store, token, value);
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
1072
|
// internal/src/molecule/create-molecule-family.ts
|
|
1231
1073
|
function createMoleculeFamily(store, options) {
|
|
1232
1074
|
const subject = new Subject();
|
|
@@ -1414,7 +1256,202 @@ function makeMoleculeInStore(store, context, familyToken, key, ...params) {
|
|
|
1414
1256
|
return token;
|
|
1415
1257
|
}
|
|
1416
1258
|
|
|
1417
|
-
// internal/src/
|
|
1259
|
+
// internal/src/families/init-family-member.ts
|
|
1260
|
+
function initFamilyMemberInStore(store, token, key) {
|
|
1261
|
+
const familyKey = token.key;
|
|
1262
|
+
const family = store.families.get(familyKey);
|
|
1263
|
+
if (family === void 0) {
|
|
1264
|
+
throw new NotFoundError(token, store);
|
|
1265
|
+
}
|
|
1266
|
+
const state = family(key);
|
|
1267
|
+
const target = newest(store);
|
|
1268
|
+
if (state.family && target.moleculeInProgress === null) {
|
|
1269
|
+
if (isRootStore(target)) {
|
|
1270
|
+
switch (state.type) {
|
|
1271
|
+
case `atom`:
|
|
1272
|
+
case `mutable_atom`:
|
|
1273
|
+
store.on.atomCreation.next(state);
|
|
1274
|
+
break;
|
|
1275
|
+
case `selector`:
|
|
1276
|
+
case `readonly_selector`:
|
|
1277
|
+
store.on.selectorCreation.next(state);
|
|
1278
|
+
break;
|
|
1279
|
+
}
|
|
1280
|
+
} else if (isChildStore(target) && target.on.transactionApplying.state === null) {
|
|
1281
|
+
target.transactionMeta.update.updates.push({
|
|
1282
|
+
type: `state_creation`,
|
|
1283
|
+
token: state
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
return state;
|
|
1288
|
+
}
|
|
1289
|
+
function seekInStore(store, token, key) {
|
|
1290
|
+
const subKey = stringifyJson(key);
|
|
1291
|
+
const fullKey = `${token.key}(${subKey})`;
|
|
1292
|
+
const target = newest(store);
|
|
1293
|
+
let state;
|
|
1294
|
+
switch (token.type) {
|
|
1295
|
+
case `atom_family`:
|
|
1296
|
+
case `mutable_atom_family`:
|
|
1297
|
+
state = target.atoms.get(fullKey);
|
|
1298
|
+
break;
|
|
1299
|
+
case `selector_family`:
|
|
1300
|
+
state = target.selectors.get(fullKey);
|
|
1301
|
+
break;
|
|
1302
|
+
case `readonly_selector_family`:
|
|
1303
|
+
state = target.readonlySelectors.get(fullKey);
|
|
1304
|
+
break;
|
|
1305
|
+
case `molecule_family`:
|
|
1306
|
+
state = target.molecules.get(stringifyJson(key));
|
|
1307
|
+
}
|
|
1308
|
+
if (state) {
|
|
1309
|
+
return deposit(state);
|
|
1310
|
+
}
|
|
1311
|
+
return state;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
// internal/src/families/find-in-store.ts
|
|
1315
|
+
function findInStore(store, token, key) {
|
|
1316
|
+
let state = seekInStore(store, token, key);
|
|
1317
|
+
if (state) {
|
|
1318
|
+
return state;
|
|
1319
|
+
}
|
|
1320
|
+
const molecule = store.molecules.get(stringifyJson(key));
|
|
1321
|
+
if (molecule) {
|
|
1322
|
+
return growMoleculeInStore(molecule, token, store);
|
|
1323
|
+
}
|
|
1324
|
+
if (store.config.lifespan === `immortal`) {
|
|
1325
|
+
const fakeToken = counterfeit(token, key);
|
|
1326
|
+
store.logger.error(
|
|
1327
|
+
`\u274C`,
|
|
1328
|
+
fakeToken.type,
|
|
1329
|
+
fakeToken.key,
|
|
1330
|
+
`was not found in store "${store.config.name}"; returned a counterfeit token.`
|
|
1331
|
+
);
|
|
1332
|
+
return fakeToken;
|
|
1333
|
+
}
|
|
1334
|
+
state = initFamilyMemberInStore(store, token, key);
|
|
1335
|
+
return state;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
// internal/src/families/dispose-from-store.ts
|
|
1339
|
+
function disposeFromStore(store, ...params) {
|
|
1340
|
+
let token;
|
|
1341
|
+
if (params.length === 1) {
|
|
1342
|
+
token = params[0];
|
|
1343
|
+
token.key;
|
|
1344
|
+
} else {
|
|
1345
|
+
const family = params[0];
|
|
1346
|
+
const key = params[1];
|
|
1347
|
+
const maybeToken = family.type === `molecule_family` ? seekInStore(store, family, key) ?? counterfeit(family, key) : findInStore(store, family, key);
|
|
1348
|
+
token = maybeToken;
|
|
1349
|
+
}
|
|
1350
|
+
try {
|
|
1351
|
+
withdraw(token, store);
|
|
1352
|
+
} catch (thrown) {
|
|
1353
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
1354
|
+
(item) => item?.key === token.key
|
|
1355
|
+
);
|
|
1356
|
+
console.log(
|
|
1357
|
+
`seeking disposal trace for`,
|
|
1358
|
+
token,
|
|
1359
|
+
store.disposalTraces.buffer.filter(Boolean)
|
|
1360
|
+
);
|
|
1361
|
+
store.logger.error(
|
|
1362
|
+
`\u274C`,
|
|
1363
|
+
token.type,
|
|
1364
|
+
token.key,
|
|
1365
|
+
`could not be disposed because it was not found in the store "${store.config.name}".`,
|
|
1366
|
+
disposal ? `
|
|
1367
|
+
This state was most recently disposed
|
|
1368
|
+
${disposal.trace}` : `No previous disposal trace was found.`
|
|
1369
|
+
);
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
switch (token.type) {
|
|
1373
|
+
case `atom`:
|
|
1374
|
+
case `mutable_atom`:
|
|
1375
|
+
disposeAtom(token, store);
|
|
1376
|
+
break;
|
|
1377
|
+
case `selector`:
|
|
1378
|
+
case `readonly_selector`:
|
|
1379
|
+
disposeSelector(token, store);
|
|
1380
|
+
break;
|
|
1381
|
+
case `molecule`:
|
|
1382
|
+
disposeMolecule(token, store);
|
|
1383
|
+
break;
|
|
1384
|
+
}
|
|
1385
|
+
const { stack } = new Error();
|
|
1386
|
+
if (stack) {
|
|
1387
|
+
const trace = stack?.split(`
|
|
1388
|
+
`)?.slice(3)?.join(`
|
|
1389
|
+
`);
|
|
1390
|
+
store.disposalTraces.add({ key: token.key, trace });
|
|
1391
|
+
console.log(`added`, token);
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
// internal/src/set-state/set-into-store.ts
|
|
1396
|
+
function setIntoStore(store, ...params) {
|
|
1397
|
+
let token;
|
|
1398
|
+
let value;
|
|
1399
|
+
if (params.length === 2) {
|
|
1400
|
+
token = params[0];
|
|
1401
|
+
value = params[1];
|
|
1402
|
+
} else {
|
|
1403
|
+
const family = params[0];
|
|
1404
|
+
const key = params[1];
|
|
1405
|
+
value = params[2];
|
|
1406
|
+
const maybeToken = findInStore(store, family, key);
|
|
1407
|
+
token = maybeToken;
|
|
1408
|
+
}
|
|
1409
|
+
if (`counterfeit` in token) {
|
|
1410
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
1411
|
+
(item) => item?.key === token.key
|
|
1412
|
+
);
|
|
1413
|
+
store.logger.error(
|
|
1414
|
+
`\u274C`,
|
|
1415
|
+
token.type,
|
|
1416
|
+
token.key,
|
|
1417
|
+
`could not be set because it was not found in the store "${store.config.name}".`,
|
|
1418
|
+
disposal ? `This state was previously disposed:
|
|
1419
|
+
${disposal.trace}` : `No previous disposal trace was found.`
|
|
1420
|
+
);
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
const rejectionTime = openOperation(token, store);
|
|
1424
|
+
if (rejectionTime) {
|
|
1425
|
+
const unsubscribe = store.on.operationClose.subscribe(
|
|
1426
|
+
`waiting to set "${token.key}" at T-${rejectionTime}`,
|
|
1427
|
+
() => {
|
|
1428
|
+
unsubscribe();
|
|
1429
|
+
store.logger.info(
|
|
1430
|
+
`\u{1F7E2}`,
|
|
1431
|
+
token.type,
|
|
1432
|
+
token.key,
|
|
1433
|
+
`resuming deferred setState from T-${rejectionTime}`
|
|
1434
|
+
);
|
|
1435
|
+
setIntoStore(store, token, value);
|
|
1436
|
+
}
|
|
1437
|
+
);
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
const state = withdraw(token, store);
|
|
1441
|
+
setAtomOrSelector(state, value, store);
|
|
1442
|
+
closeOperation(store);
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
// internal/src/ingest-updates/ingest-atom-update.ts
|
|
1446
|
+
function ingestAtomUpdate(applying, atomUpdate, store) {
|
|
1447
|
+
const { key, newValue, oldValue } = atomUpdate;
|
|
1448
|
+
const value = applying === `newValue` ? newValue : oldValue;
|
|
1449
|
+
const token = { key, type: `atom` };
|
|
1450
|
+
if (atomUpdate.family) {
|
|
1451
|
+
Object.assign(token, { family: atomUpdate.family });
|
|
1452
|
+
}
|
|
1453
|
+
setIntoStore(store, token, value);
|
|
1454
|
+
}
|
|
1418
1455
|
function ingestCreationEvent(update, applying, store) {
|
|
1419
1456
|
switch (applying) {
|
|
1420
1457
|
case `newValue`: {
|
|
@@ -1450,7 +1487,16 @@ function createInStore(token, store) {
|
|
|
1450
1487
|
return;
|
|
1451
1488
|
}
|
|
1452
1489
|
if (store.config.lifespan === `immortal`) {
|
|
1453
|
-
|
|
1490
|
+
store.logger.error(
|
|
1491
|
+
`\u{1F41E}`,
|
|
1492
|
+
`atom`,
|
|
1493
|
+
token.family.key,
|
|
1494
|
+
`tried to create member`,
|
|
1495
|
+
`"${token.family.subKey}"`,
|
|
1496
|
+
`but a molecule with that key was not found in store`,
|
|
1497
|
+
`"${store.config.name}"`
|
|
1498
|
+
);
|
|
1499
|
+
return;
|
|
1454
1500
|
}
|
|
1455
1501
|
initFamilyMemberInStore(store, family, parseJson(token.family.subKey));
|
|
1456
1502
|
}
|
|
@@ -1676,6 +1722,7 @@ var buildTransaction = (key, params, store, id) => {
|
|
|
1676
1722
|
selectors: new LazyMap(parent.selectors),
|
|
1677
1723
|
valueMap: new LazyMap(parent.valueMap),
|
|
1678
1724
|
defaults: parent.defaults,
|
|
1725
|
+
disposalTraces: store.disposalTraces.copy(),
|
|
1679
1726
|
molecules: new LazyMap(parent.molecules),
|
|
1680
1727
|
moleculeFamilies: new LazyMap(parent.moleculeFamilies),
|
|
1681
1728
|
moleculeInProgress: parent.moleculeInProgress,
|
|
@@ -1773,6 +1820,36 @@ function getEpochNumberOfAction(transactionKey, store) {
|
|
|
1773
1820
|
// internal/src/transaction/index.ts
|
|
1774
1821
|
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
1775
1822
|
|
|
1823
|
+
// internal/src/store/circular-buffer.ts
|
|
1824
|
+
var CircularBuffer = class _CircularBuffer {
|
|
1825
|
+
_buffer;
|
|
1826
|
+
_index = 0;
|
|
1827
|
+
constructor(lengthOrArray) {
|
|
1828
|
+
let length;
|
|
1829
|
+
if (typeof lengthOrArray === `number`) {
|
|
1830
|
+
length = lengthOrArray;
|
|
1831
|
+
} else {
|
|
1832
|
+
length = lengthOrArray.length;
|
|
1833
|
+
}
|
|
1834
|
+
this._buffer = Array.from({ length });
|
|
1835
|
+
}
|
|
1836
|
+
get buffer() {
|
|
1837
|
+
return this._buffer;
|
|
1838
|
+
}
|
|
1839
|
+
get index() {
|
|
1840
|
+
return this._index;
|
|
1841
|
+
}
|
|
1842
|
+
add(item) {
|
|
1843
|
+
this._buffer[this._index] = item;
|
|
1844
|
+
this._index = (this._index + 1) % this._buffer.length;
|
|
1845
|
+
}
|
|
1846
|
+
copy() {
|
|
1847
|
+
const copy = new _CircularBuffer([...this._buffer]);
|
|
1848
|
+
copy._index = this._index;
|
|
1849
|
+
return copy;
|
|
1850
|
+
}
|
|
1851
|
+
};
|
|
1852
|
+
|
|
1776
1853
|
// internal/src/store/store.ts
|
|
1777
1854
|
var Store = class {
|
|
1778
1855
|
parent = null;
|
|
@@ -1811,6 +1888,7 @@ var Store = class {
|
|
|
1811
1888
|
between: [`timelineKey`, `topicKey`],
|
|
1812
1889
|
cardinality: `1:n`
|
|
1813
1890
|
});
|
|
1891
|
+
disposalTraces = new CircularBuffer(100);
|
|
1814
1892
|
molecules = /* @__PURE__ */ new Map();
|
|
1815
1893
|
moleculeFamilies = /* @__PURE__ */ new Map();
|
|
1816
1894
|
moleculeInProgress = null;
|
|
@@ -2625,15 +2703,8 @@ function createStandaloneAtom(store, options) {
|
|
|
2625
2703
|
function disposeAtom(atomToken, store) {
|
|
2626
2704
|
const target = newest(store);
|
|
2627
2705
|
const { key } = atomToken;
|
|
2628
|
-
const atom = target
|
|
2629
|
-
if (!atom) {
|
|
2630
|
-
store.logger.error(
|
|
2631
|
-
`\u274C`,
|
|
2632
|
-
`atom`,
|
|
2633
|
-
key,
|
|
2634
|
-
`Tried to dispose atom, but it does not exist in the store.`
|
|
2635
|
-
);
|
|
2636
|
-
} else if (!atom.family) {
|
|
2706
|
+
const atom = withdraw(atomToken, target);
|
|
2707
|
+
if (!atom.family) {
|
|
2637
2708
|
store.logger.error(`\u274C`, `atom`, key, `Standalone atoms cannot be disposed.`);
|
|
2638
2709
|
} else {
|
|
2639
2710
|
atom.cleanup?.();
|
|
@@ -3171,4 +3242,4 @@ var timeTravel = (store, action, token) => {
|
|
|
3171
3242
|
);
|
|
3172
3243
|
};
|
|
3173
3244
|
|
|
3174
|
-
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, createWritableSelectorFamily, 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, recallState, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootAtoms, subscribeToState2 as subscribeToState, subscribeToTimeline2 as subscribeToTimeline, subscribeToTransaction2 as subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
|
|
3245
|
+
export { FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, LazyMap, Molecule, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, counterfeit, createAtomFamily, createMoleculeFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, createWritableSelectorFamily, 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, recallState, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootAtoms, subscribeToState2 as subscribeToState, subscribeToTimeline2 as subscribeToTimeline, subscribeToTransaction2 as subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
|