atom.io 0.18.3 → 0.19.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.cjs +173 -1
- package/data/dist/index.d.ts +52 -21
- package/data/dist/index.js +12 -331
- package/data/src/join.ts +309 -41
- package/dist/chunk-7ZR244C2.js +489 -0
- package/package.json +3 -3
- package/realtime/dist/index.cjs +4 -2
- package/realtime/dist/index.d.ts +1 -96
- package/realtime/dist/index.js +5 -3
- package/realtime/src/shared-room-store.ts +5 -3
- package/realtime-server/dist/index.cjs +162 -18
- package/realtime-server/dist/index.d.ts +1 -91
- package/realtime-server/dist/index.js +31 -17
- package/realtime-server/src/realtime-continuity-synchronizer.ts +8 -6
- package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +22 -10
- package/realtime-testing/dist/index.cjs +48 -6
- package/realtime-testing/dist/index.js +9 -2
- package/realtime-testing/src/setup-realtime-test.tsx +8 -2
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
import { Junction } from './chunk-WX2NCOZR.js';
|
|
2
|
+
import { dispose } from 'atom.io';
|
|
3
|
+
import { getFromStore, setIntoStore, findInStore, createMutableAtomFamily, createRegularAtomFamily, IMPLICIT, newest, isChildStore, createSelectorFamily, getJsonFamily } from 'atom.io/internal';
|
|
4
|
+
import { SetRTX } from 'atom.io/transceivers/set-rtx';
|
|
5
|
+
|
|
6
|
+
function capitalize(string) {
|
|
7
|
+
return string[0].toUpperCase() + string.slice(1);
|
|
8
|
+
}
|
|
9
|
+
var Join = class _Join {
|
|
10
|
+
transact(transactors, run) {
|
|
11
|
+
const originalTransactors = this.transactors;
|
|
12
|
+
this.transactors = transactors;
|
|
13
|
+
run(this);
|
|
14
|
+
this.transactors = originalTransactors;
|
|
15
|
+
}
|
|
16
|
+
in(store) {
|
|
17
|
+
const key = store.config.name;
|
|
18
|
+
const alternate = this.alternates.get(key);
|
|
19
|
+
if (alternate) {
|
|
20
|
+
return alternate;
|
|
21
|
+
}
|
|
22
|
+
const join2 = new _Join(this.options, this.defaultContent, store);
|
|
23
|
+
this.alternates.set(key, join2);
|
|
24
|
+
join2.alternates = this.alternates;
|
|
25
|
+
return join2;
|
|
26
|
+
}
|
|
27
|
+
constructor(options, defaultContent, store = IMPLICIT.STORE) {
|
|
28
|
+
this.options = options;
|
|
29
|
+
this.defaultContent = defaultContent;
|
|
30
|
+
this.alternates = /* @__PURE__ */ new Map();
|
|
31
|
+
this.alternates.set(store.config.name, this);
|
|
32
|
+
this.transactors = {
|
|
33
|
+
get: (token) => getFromStore(token, store),
|
|
34
|
+
set: (token, value) => setIntoStore(token, value, store),
|
|
35
|
+
find: (token, key) => findInStore(token, key, store)
|
|
36
|
+
};
|
|
37
|
+
const a = options.between[0];
|
|
38
|
+
const b = options.between[1];
|
|
39
|
+
const relatedKeysAtoms = createMutableAtomFamily(
|
|
40
|
+
{
|
|
41
|
+
key: `${options.key}/relatedKeys`,
|
|
42
|
+
default: () => new SetRTX(),
|
|
43
|
+
mutable: true,
|
|
44
|
+
fromJson: (json) => SetRTX.fromJSON(json),
|
|
45
|
+
toJson: (set) => set.toJSON()
|
|
46
|
+
},
|
|
47
|
+
store
|
|
48
|
+
);
|
|
49
|
+
this.core = { findRelatedKeysState: relatedKeysAtoms };
|
|
50
|
+
const getRelatedKeys = ({ find, get }, key) => get(find(relatedKeysAtoms, key));
|
|
51
|
+
const addRelation = (transactors, a2, b2) => {
|
|
52
|
+
const { set, find } = transactors;
|
|
53
|
+
const aKeysState = find(relatedKeysAtoms, a2);
|
|
54
|
+
const bKeysState = find(relatedKeysAtoms, b2);
|
|
55
|
+
set(aKeysState, (aKeys) => aKeys.add(b2));
|
|
56
|
+
set(bKeysState, (bKeys) => bKeys.add(a2));
|
|
57
|
+
};
|
|
58
|
+
const deleteRelation = (transactors, a2, b2) => {
|
|
59
|
+
const { find, set } = transactors;
|
|
60
|
+
const aKeysState = find(relatedKeysAtoms, a2);
|
|
61
|
+
const bKeysState = find(relatedKeysAtoms, b2);
|
|
62
|
+
set(aKeysState, (aKeys) => (aKeys.delete(b2), aKeys));
|
|
63
|
+
set(bKeysState, (bKeys) => (bKeys.delete(a2), bKeys));
|
|
64
|
+
};
|
|
65
|
+
const replaceRelationsSafely = (transactors, a2, newRelationsOfA) => {
|
|
66
|
+
const { find, get, set } = transactors;
|
|
67
|
+
const relationsOfAState = find(relatedKeysAtoms, a2);
|
|
68
|
+
const currentRelationsOfA = get(relationsOfAState);
|
|
69
|
+
for (const currentRelationB of currentRelationsOfA) {
|
|
70
|
+
const remainsRelated = newRelationsOfA.includes(currentRelationB);
|
|
71
|
+
if (remainsRelated) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const relationsOfBState = find(relatedKeysAtoms, currentRelationB);
|
|
75
|
+
set(relationsOfBState, (relationsOfB) => {
|
|
76
|
+
relationsOfB.delete(a2);
|
|
77
|
+
return relationsOfB;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
set(relationsOfAState, (relationsOfA) => {
|
|
81
|
+
relationsOfA.transaction((nextRelationsOfA) => {
|
|
82
|
+
nextRelationsOfA.clear();
|
|
83
|
+
for (const newRelationB of newRelationsOfA) {
|
|
84
|
+
const relationsOfB = getRelatedKeys(transactors, newRelationB);
|
|
85
|
+
const newRelationBIsAlreadyRelated = relationsOfB.has(a2);
|
|
86
|
+
if (this.relations.cardinality === `1:n`) {
|
|
87
|
+
for (const previousOwner of relationsOfB) {
|
|
88
|
+
if (previousOwner === a2) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const previousOwnerRelations = getRelatedKeys(
|
|
92
|
+
transactors,
|
|
93
|
+
previousOwner
|
|
94
|
+
);
|
|
95
|
+
previousOwnerRelations.delete(newRelationB);
|
|
96
|
+
}
|
|
97
|
+
if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0) {
|
|
98
|
+
relationsOfB.clear();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!newRelationBIsAlreadyRelated) {
|
|
102
|
+
relationsOfB.add(a2);
|
|
103
|
+
}
|
|
104
|
+
nextRelationsOfA.add(newRelationB);
|
|
105
|
+
}
|
|
106
|
+
return true;
|
|
107
|
+
});
|
|
108
|
+
return relationsOfA;
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
const replaceRelationsUnsafely = (transactors, a2, newRelationsOfA) => {
|
|
112
|
+
const { find, set } = transactors;
|
|
113
|
+
const relationsOfAState = find(relatedKeysAtoms, a2);
|
|
114
|
+
set(relationsOfAState, (relationsOfA) => {
|
|
115
|
+
relationsOfA.transaction((nextRelationsOfA) => {
|
|
116
|
+
for (const newRelationB of newRelationsOfA) {
|
|
117
|
+
nextRelationsOfA.add(newRelationB);
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
});
|
|
121
|
+
return relationsOfA;
|
|
122
|
+
});
|
|
123
|
+
for (const newRelationB of newRelationsOfA) {
|
|
124
|
+
const newRelationsBState = find(relatedKeysAtoms, newRelationB);
|
|
125
|
+
set(newRelationsBState, (newRelationsB) => {
|
|
126
|
+
newRelationsB.add(a2);
|
|
127
|
+
return newRelationsB;
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return true;
|
|
131
|
+
};
|
|
132
|
+
const has = (transactors, a2, b2) => {
|
|
133
|
+
const aKeys = getRelatedKeys(transactors, a2);
|
|
134
|
+
return b2 ? aKeys.has(b2) : aKeys.size > 0;
|
|
135
|
+
};
|
|
136
|
+
const baseExternalStoreConfiguration = {
|
|
137
|
+
getRelatedKeys: (key) => getRelatedKeys(this.transactors, key),
|
|
138
|
+
addRelation: (a2, b2) => addRelation(this.transactors, a2, b2),
|
|
139
|
+
deleteRelation: (a2, b2) => deleteRelation(this.transactors, a2, b2),
|
|
140
|
+
replaceRelationsSafely: (a2, bs) => replaceRelationsSafely(this.transactors, a2, bs),
|
|
141
|
+
replaceRelationsUnsafely: (a2, bs) => replaceRelationsUnsafely(this.transactors, a2, bs),
|
|
142
|
+
has: (a2, b2) => has(this.transactors, a2, b2)
|
|
143
|
+
};
|
|
144
|
+
let externalStore;
|
|
145
|
+
let contentAtoms;
|
|
146
|
+
if (defaultContent) {
|
|
147
|
+
contentAtoms = createRegularAtomFamily(
|
|
148
|
+
{
|
|
149
|
+
key: `${options.key}/content`,
|
|
150
|
+
default: defaultContent
|
|
151
|
+
},
|
|
152
|
+
store
|
|
153
|
+
);
|
|
154
|
+
const getContent = ({ find, get }, key) => get(find(contentAtoms, key));
|
|
155
|
+
const setContent = ({ find, set }, key, content) => set(find(contentAtoms, key), content);
|
|
156
|
+
const deleteContent = ({ find }, key) => dispose(find(contentAtoms, key));
|
|
157
|
+
const externalStoreWithContentConfiguration = {
|
|
158
|
+
getContent: (contentKey) => {
|
|
159
|
+
const content = getContent(this.transactors, contentKey);
|
|
160
|
+
return content;
|
|
161
|
+
},
|
|
162
|
+
setContent: (contentKey, content) => {
|
|
163
|
+
setContent(this.transactors, contentKey, content);
|
|
164
|
+
},
|
|
165
|
+
deleteContent: (contentKey) => {
|
|
166
|
+
deleteContent(this.transactors, contentKey);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
externalStore = Object.assign(
|
|
170
|
+
baseExternalStoreConfiguration,
|
|
171
|
+
externalStoreWithContentConfiguration
|
|
172
|
+
);
|
|
173
|
+
} else {
|
|
174
|
+
externalStore = baseExternalStoreConfiguration;
|
|
175
|
+
}
|
|
176
|
+
const relations = new Junction(options, {
|
|
177
|
+
externalStore,
|
|
178
|
+
makeContentKey: (...args) => args.sort().join(`:`)
|
|
179
|
+
});
|
|
180
|
+
const createSingleKeyStateFamily = () => createSelectorFamily(
|
|
181
|
+
{
|
|
182
|
+
key: `${options.key}/singleRelatedKey`,
|
|
183
|
+
get: (key) => ({ find, get }) => {
|
|
184
|
+
const relatedKeysState = find(relatedKeysAtoms, key);
|
|
185
|
+
const relatedKeys = get(relatedKeysState);
|
|
186
|
+
for (const relatedKey of relatedKeys) {
|
|
187
|
+
return relatedKey;
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
store
|
|
193
|
+
);
|
|
194
|
+
const getMultipleKeyStateFamily = () => {
|
|
195
|
+
return createSelectorFamily(
|
|
196
|
+
{
|
|
197
|
+
key: `${options.key}/multipleRelatedKeys`,
|
|
198
|
+
get: (key) => ({ find, get }) => {
|
|
199
|
+
const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
|
|
200
|
+
const jsonState = find(jsonFamily, key);
|
|
201
|
+
const json = get(jsonState);
|
|
202
|
+
return json.members;
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
store
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
const createSingleEntryStateFamily = () => createSelectorFamily(
|
|
209
|
+
{
|
|
210
|
+
key: `${options.key}/singleRelatedEntry`,
|
|
211
|
+
get: (key) => ({ find, get }) => {
|
|
212
|
+
const relatedKeysState = find(relatedKeysAtoms, key);
|
|
213
|
+
const relatedKeys = get(relatedKeysState);
|
|
214
|
+
for (const relatedKey of relatedKeys) {
|
|
215
|
+
const contentKey = relations.makeContentKey(key, relatedKey);
|
|
216
|
+
const contentState = find(contentAtoms, contentKey);
|
|
217
|
+
const content = get(contentState);
|
|
218
|
+
return [relatedKey, content];
|
|
219
|
+
}
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
store
|
|
224
|
+
);
|
|
225
|
+
const getMultipleEntryStateFamily = () => createSelectorFamily(
|
|
226
|
+
{
|
|
227
|
+
key: `${options.key}/multipleRelatedEntries`,
|
|
228
|
+
get: (key) => ({ find, get }) => {
|
|
229
|
+
const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
|
|
230
|
+
const json = get(jsonFamily(key));
|
|
231
|
+
return json.members.map((relatedKey) => {
|
|
232
|
+
const contentKey = relations.makeContentKey(key, relatedKey);
|
|
233
|
+
const contentState = find(contentAtoms, contentKey);
|
|
234
|
+
const content = get(contentState);
|
|
235
|
+
return [relatedKey, content];
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
store
|
|
240
|
+
);
|
|
241
|
+
switch (options.cardinality) {
|
|
242
|
+
case `1:1`: {
|
|
243
|
+
const findSingleRelatedKeyState = createSingleKeyStateFamily();
|
|
244
|
+
const stateKeyA = `${a}KeyOf${capitalize(b)}`;
|
|
245
|
+
const stateKeyB = `${b}KeyOf${capitalize(a)}`;
|
|
246
|
+
const baseStates = {
|
|
247
|
+
[stateKeyA]: findSingleRelatedKeyState,
|
|
248
|
+
[stateKeyB]: findSingleRelatedKeyState
|
|
249
|
+
};
|
|
250
|
+
let states;
|
|
251
|
+
if (defaultContent) {
|
|
252
|
+
const findSingleRelatedEntryState = createSingleEntryStateFamily();
|
|
253
|
+
const entriesStateKeyA = `${a}EntryOf${capitalize(b)}`;
|
|
254
|
+
const entriesStateKeyB = `${b}EntryOf${capitalize(a)}`;
|
|
255
|
+
const contentStates = {
|
|
256
|
+
[entriesStateKeyA]: findSingleRelatedEntryState,
|
|
257
|
+
[entriesStateKeyB]: findSingleRelatedEntryState
|
|
258
|
+
};
|
|
259
|
+
states = Object.assign(baseStates, contentStates);
|
|
260
|
+
} else {
|
|
261
|
+
states = baseStates;
|
|
262
|
+
}
|
|
263
|
+
this.relations = relations;
|
|
264
|
+
this.states = states;
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
case `1:n`: {
|
|
268
|
+
const findSingleRelatedKeyState = createSingleKeyStateFamily();
|
|
269
|
+
const findMultipleRelatedKeysState = getMultipleKeyStateFamily();
|
|
270
|
+
const stateKeyA = `${a}KeyOf${capitalize(b)}`;
|
|
271
|
+
const stateKeyB = `${b}KeysOf${capitalize(a)}`;
|
|
272
|
+
const baseStates = {
|
|
273
|
+
[stateKeyA]: findSingleRelatedKeyState,
|
|
274
|
+
[stateKeyB]: findMultipleRelatedKeysState
|
|
275
|
+
};
|
|
276
|
+
let states;
|
|
277
|
+
if (defaultContent) {
|
|
278
|
+
const findSingleRelatedEntryState = createSingleEntryStateFamily();
|
|
279
|
+
const findMultipleRelatedEntriesState = getMultipleEntryStateFamily();
|
|
280
|
+
const entriesStateKeyA = `${a}EntryOf${capitalize(b)}`;
|
|
281
|
+
const entriesStateKeyB = `${b}EntriesOf${capitalize(a)}`;
|
|
282
|
+
const contentStates = {
|
|
283
|
+
[entriesStateKeyA]: findSingleRelatedEntryState,
|
|
284
|
+
[entriesStateKeyB]: findMultipleRelatedEntriesState
|
|
285
|
+
};
|
|
286
|
+
states = Object.assign(baseStates, contentStates);
|
|
287
|
+
} else {
|
|
288
|
+
states = baseStates;
|
|
289
|
+
}
|
|
290
|
+
this.relations = relations;
|
|
291
|
+
this.states = states;
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
default: {
|
|
295
|
+
const findMultipleRelatedKeysState = getMultipleKeyStateFamily();
|
|
296
|
+
const stateKeyA = `${a}KeysOf${capitalize(b)}`;
|
|
297
|
+
const stateKeyB = `${b}KeysOf${capitalize(a)}`;
|
|
298
|
+
const baseStates = {
|
|
299
|
+
[stateKeyA]: findMultipleRelatedKeysState,
|
|
300
|
+
[stateKeyB]: findMultipleRelatedKeysState
|
|
301
|
+
};
|
|
302
|
+
let states;
|
|
303
|
+
if (defaultContent) {
|
|
304
|
+
const findMultipleRelatedEntriesState = getMultipleEntryStateFamily();
|
|
305
|
+
const entriesStateKeyA = `${a}EntriesOf${capitalize(b)}`;
|
|
306
|
+
const entriesStateKeyB = `${b}EntriesOf${capitalize(a)}`;
|
|
307
|
+
const contentStates = {
|
|
308
|
+
[entriesStateKeyA]: findMultipleRelatedEntriesState,
|
|
309
|
+
[entriesStateKeyB]: findMultipleRelatedEntriesState
|
|
310
|
+
};
|
|
311
|
+
states = Object.assign(baseStates, contentStates);
|
|
312
|
+
} else {
|
|
313
|
+
states = baseStates;
|
|
314
|
+
}
|
|
315
|
+
this.relations = relations;
|
|
316
|
+
this.states = states;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
function join(options, defaultContent, store = IMPLICIT.STORE) {
|
|
322
|
+
const joins = getJoinMap(store);
|
|
323
|
+
joins.set(options.key, new Join(options, defaultContent, store));
|
|
324
|
+
const token = {
|
|
325
|
+
key: options.key,
|
|
326
|
+
type: `join`,
|
|
327
|
+
a: options.between[0],
|
|
328
|
+
b: options.between[1],
|
|
329
|
+
cardinality: options.cardinality
|
|
330
|
+
};
|
|
331
|
+
return token;
|
|
332
|
+
}
|
|
333
|
+
function getJoinMap(store) {
|
|
334
|
+
if (`joins` in store && store.joins instanceof Map) {
|
|
335
|
+
return store.joins;
|
|
336
|
+
}
|
|
337
|
+
const joins = /* @__PURE__ */ new Map();
|
|
338
|
+
store.joins = joins;
|
|
339
|
+
return joins;
|
|
340
|
+
}
|
|
341
|
+
function getJoin(token, store) {
|
|
342
|
+
var _a;
|
|
343
|
+
const joinMap = getJoinMap(store);
|
|
344
|
+
let join2 = joinMap.get(token.key);
|
|
345
|
+
if (join2 === void 0) {
|
|
346
|
+
const rootJoinMap = getJoinMap(IMPLICIT.STORE);
|
|
347
|
+
join2 = (_a = rootJoinMap.get(token.key)) == null ? void 0 : _a.in(store);
|
|
348
|
+
if (join2 === void 0) {
|
|
349
|
+
throw new Error(
|
|
350
|
+
`Join "${token.key}" not found in store "${store.config.name}"`
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
joinMap.set(token.key, join2);
|
|
354
|
+
}
|
|
355
|
+
return join2;
|
|
356
|
+
}
|
|
357
|
+
function findRelationsInStore(token, key, store) {
|
|
358
|
+
const join2 = getJoin(token, store);
|
|
359
|
+
let relations;
|
|
360
|
+
switch (token.cardinality) {
|
|
361
|
+
case `1:1`: {
|
|
362
|
+
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
363
|
+
const keyBA = `${token.b}KeyOf${capitalize(token.a)}`;
|
|
364
|
+
relations = {
|
|
365
|
+
get [keyAB]() {
|
|
366
|
+
const familyAB = join2.states[keyAB];
|
|
367
|
+
const state = findInStore(familyAB, key, store);
|
|
368
|
+
return state;
|
|
369
|
+
},
|
|
370
|
+
get [keyBA]() {
|
|
371
|
+
const familyBA = join2.states[keyBA];
|
|
372
|
+
const state = findInStore(familyBA, key, store);
|
|
373
|
+
return state;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
|
|
377
|
+
if (entryAB in join2.states) {
|
|
378
|
+
const entryBA = `${token.b}EntryOf${capitalize(token.a)}`;
|
|
379
|
+
Object.assign(relations, {
|
|
380
|
+
get [entryAB]() {
|
|
381
|
+
const familyAB = join2.states[entryAB];
|
|
382
|
+
const state = findInStore(familyAB, key, store);
|
|
383
|
+
return state;
|
|
384
|
+
},
|
|
385
|
+
get [entryBA]() {
|
|
386
|
+
const familyBA = join2.states[entryBA];
|
|
387
|
+
const state = findInStore(familyBA, key, store);
|
|
388
|
+
return state;
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
case `1:n`: {
|
|
395
|
+
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
396
|
+
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
397
|
+
relations = {
|
|
398
|
+
get [keyAB]() {
|
|
399
|
+
const familyAB = join2.states[keyAB];
|
|
400
|
+
const state = findInStore(familyAB, key, store);
|
|
401
|
+
return state;
|
|
402
|
+
},
|
|
403
|
+
get [keysBA]() {
|
|
404
|
+
const familyBA = join2.states[keysBA];
|
|
405
|
+
const state = findInStore(familyBA, key, store);
|
|
406
|
+
return state;
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
|
|
410
|
+
if (entryAB in join2.states) {
|
|
411
|
+
const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
|
|
412
|
+
Object.assign(relations, {
|
|
413
|
+
get [entryAB]() {
|
|
414
|
+
const familyAB = join2.states[entryAB];
|
|
415
|
+
const state = findInStore(familyAB, key, store);
|
|
416
|
+
return state;
|
|
417
|
+
},
|
|
418
|
+
get [entriesBA]() {
|
|
419
|
+
const familyBA = join2.states[entriesBA];
|
|
420
|
+
const state = findInStore(familyBA, key, store);
|
|
421
|
+
return state;
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
case `n:n`: {
|
|
428
|
+
const keysAB = `${token.a}KeysOf${capitalize(token.b)}`;
|
|
429
|
+
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
430
|
+
relations = {
|
|
431
|
+
get [keysAB]() {
|
|
432
|
+
const familyAB = join2.states[keysAB];
|
|
433
|
+
const state = findInStore(familyAB, key, store);
|
|
434
|
+
return state;
|
|
435
|
+
},
|
|
436
|
+
get [keysBA]() {
|
|
437
|
+
const familyBA = join2.states[keysBA];
|
|
438
|
+
const state = findInStore(familyBA, key, store);
|
|
439
|
+
return state;
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`;
|
|
443
|
+
if (entriesAB in join2.states) {
|
|
444
|
+
const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
|
|
445
|
+
Object.assign(relations, {
|
|
446
|
+
get [entriesAB]() {
|
|
447
|
+
const familyAB = join2.states[entriesAB];
|
|
448
|
+
const state = findInStore(familyAB, key, store);
|
|
449
|
+
return state;
|
|
450
|
+
},
|
|
451
|
+
get [entriesBA]() {
|
|
452
|
+
const familyBA = join2.states[entriesBA];
|
|
453
|
+
const state = findInStore(familyBA, key, store);
|
|
454
|
+
return state;
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return relations;
|
|
461
|
+
}
|
|
462
|
+
function findRelations(token, key) {
|
|
463
|
+
return findRelationsInStore(token, key, IMPLICIT.STORE);
|
|
464
|
+
}
|
|
465
|
+
function editRelationsInStore(token, change, store) {
|
|
466
|
+
const join2 = getJoin(token, store);
|
|
467
|
+
const target = newest(store);
|
|
468
|
+
if (isChildStore(target)) {
|
|
469
|
+
const { transactors } = target.transactionMeta;
|
|
470
|
+
join2.transact(transactors, ({ relations }) => {
|
|
471
|
+
change(relations);
|
|
472
|
+
});
|
|
473
|
+
} else {
|
|
474
|
+
change(join2.relations);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
function editRelations(token, change) {
|
|
478
|
+
editRelationsInStore(token, change, IMPLICIT.STORE);
|
|
479
|
+
}
|
|
480
|
+
function getInternalRelationsFromStore(token, store) {
|
|
481
|
+
const join2 = getJoin(token, store);
|
|
482
|
+
const family = join2.core.findRelatedKeysState;
|
|
483
|
+
return family;
|
|
484
|
+
}
|
|
485
|
+
function getInternalRelations(token) {
|
|
486
|
+
return getInternalRelationsFromStore(token, IMPLICIT.STORE);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
export { Join, editRelations, editRelationsInStore, findRelations, findRelationsInStore, getInternalRelations, getInternalRelationsFromStore, getJoin, getJoinMap, join };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atom.io",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Composable and testable reactive data library.",
|
|
5
5
|
"homepage": "https://atom.io.fyi",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"@testing-library/react": "14.2.1",
|
|
79
79
|
"@types/http-proxy": "1.17.14",
|
|
80
80
|
"@types/npmlog": "7.0.0",
|
|
81
|
-
"@types/react": "18.2.
|
|
81
|
+
"@types/react": "18.2.62",
|
|
82
82
|
"@types/tmp": "0.2.6",
|
|
83
83
|
"@vitest/coverage-v8": "1.3.1",
|
|
84
84
|
"@vitest/ui": "1.3.1",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"tmp": "0.2.3",
|
|
101
101
|
"tsup": "8.0.2",
|
|
102
102
|
"typescript": "5.3.3",
|
|
103
|
-
"vite": "5.1.
|
|
103
|
+
"vite": "5.1.5",
|
|
104
104
|
"vite-tsconfig-paths": "4.3.1",
|
|
105
105
|
"vitest": "1.3.1"
|
|
106
106
|
},
|
package/realtime/dist/index.cjs
CHANGED
|
@@ -103,8 +103,10 @@ var usersInRooms = data.join(
|
|
|
103
103
|
);
|
|
104
104
|
var usersInMyRoomView = atom_io.selectorFamily({
|
|
105
105
|
key: `usersInMyRoomView`,
|
|
106
|
-
get: (
|
|
107
|
-
|
|
106
|
+
get: (myUsername) => ({ find }) => {
|
|
107
|
+
const usersInRoomsAtoms = data.getInternalRelations(usersInRooms);
|
|
108
|
+
const myRoomIndex = find(usersInRoomsAtoms, myUsername);
|
|
109
|
+
return [myRoomIndex];
|
|
108
110
|
}
|
|
109
111
|
});
|
|
110
112
|
|
package/realtime/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import * as atom_io from 'atom.io';
|
|
|
2
2
|
import { AtomFamilyToken, ReadableFamilyToken, ReadableToken, AtomToken, TransactionToken, MutableAtomToken } from 'atom.io';
|
|
3
3
|
import { Json } from 'atom.io/json';
|
|
4
4
|
import * as atom_io_data from 'atom.io/data';
|
|
5
|
-
import * as atom_io_internal from 'atom.io/internal';
|
|
6
5
|
import { SetRTX, SetRTXJson } from 'atom.io/transceivers/set-rtx';
|
|
7
6
|
|
|
8
7
|
declare class InvariantMap<K, V> extends Map<K, V> {
|
|
@@ -40,107 +39,13 @@ type ContinuityOptions = {
|
|
|
40
39
|
};
|
|
41
40
|
declare function continuity(options: ContinuityOptions): ContinuityToken;
|
|
42
41
|
|
|
43
|
-
type primitive = boolean | number | string | null;
|
|
44
|
-
|
|
45
|
-
type Serializable = primitive | Readonly<{
|
|
46
|
-
[key: string]: Serializable;
|
|
47
|
-
}> | ReadonlyArray<Serializable>;
|
|
48
|
-
type Object$1<Key extends string = string, Value extends Serializable = Serializable> = Record<Key, Value>;
|
|
49
|
-
|
|
50
|
-
type Refinement<Unrefined, Refined extends Unrefined> = (value: Unrefined) => value is Refined;
|
|
51
|
-
type Cardinality = `1:1` | `1:n` | `n:n`;
|
|
52
|
-
|
|
53
|
-
interface JunctionEntries<Content extends Object$1 | null> extends Object$1 {
|
|
54
|
-
readonly relations: [string, string[]][];
|
|
55
|
-
readonly contents: [string, Content][];
|
|
56
|
-
}
|
|
57
|
-
interface JunctionSchema<ASide extends string, BSide extends string> extends Object$1 {
|
|
58
|
-
readonly between: [a: ASide, b: BSide];
|
|
59
|
-
readonly cardinality: Cardinality;
|
|
60
|
-
}
|
|
61
|
-
type BaseExternalStoreConfiguration = {
|
|
62
|
-
addRelation: (a: string, b: string) => void;
|
|
63
|
-
deleteRelation: (a: string, b: string) => void;
|
|
64
|
-
replaceRelationsSafely: (a: string, bs: string[]) => void;
|
|
65
|
-
replaceRelationsUnsafely: (a: string, bs: string[]) => void;
|
|
66
|
-
getRelatedKeys: (key: string) => Set<string> | undefined;
|
|
67
|
-
has: (a: string, b?: string) => boolean;
|
|
68
|
-
};
|
|
69
|
-
type ExternalStoreWithContentConfiguration<Content extends Object$1> = {
|
|
70
|
-
getContent: (contentKey: string) => Content | undefined;
|
|
71
|
-
setContent: (contentKey: string, content: Content) => void;
|
|
72
|
-
deleteContent: (contentKey: string) => void;
|
|
73
|
-
};
|
|
74
|
-
type Empty<Obj extends object> = {
|
|
75
|
-
[Key in keyof Obj]?: undefined;
|
|
76
|
-
};
|
|
77
|
-
type ExternalStoreConfiguration<Content extends Object$1 | null> = Content extends Object$1 ? BaseExternalStoreConfiguration & ExternalStoreWithContentConfiguration<Content> : BaseExternalStoreConfiguration & Empty<ExternalStoreWithContentConfiguration<Object$1>>;
|
|
78
|
-
type JunctionAdvancedConfiguration<Content extends Object$1 | null> = {
|
|
79
|
-
externalStore?: ExternalStoreConfiguration<Content>;
|
|
80
|
-
isContent?: Refinement<unknown, Content>;
|
|
81
|
-
makeContentKey?: (a: string, b: string) => string;
|
|
82
|
-
};
|
|
83
|
-
type JunctionJSON<ASide extends string, BSide extends string, Content extends Object$1 | null> = JunctionEntries<Content> & JunctionSchema<ASide, BSide>;
|
|
84
|
-
declare class Junction<const ASide extends string, const BSide extends string, const Content extends Object$1 | null = null> {
|
|
85
|
-
readonly a: ASide;
|
|
86
|
-
readonly b: BSide;
|
|
87
|
-
readonly cardinality: Cardinality;
|
|
88
|
-
readonly relations: Map<string, Set<string>>;
|
|
89
|
-
readonly contents: Map<string, Content>;
|
|
90
|
-
isContent: Refinement<unknown, Content> | null;
|
|
91
|
-
makeContentKey: (a: string, b: string) => string;
|
|
92
|
-
getRelatedKeys(key: string): Set<string> | undefined;
|
|
93
|
-
protected addRelation(a: string, b: string): void;
|
|
94
|
-
protected deleteRelation(a: string, b: string): void;
|
|
95
|
-
protected replaceRelationsUnsafely(a: string, bs: string[]): void;
|
|
96
|
-
protected replaceRelationsSafely(a: string, bs: string[]): void;
|
|
97
|
-
protected getContentInternal(contentKey: string): Content | undefined;
|
|
98
|
-
protected setContent(contentKey: string, content: Content): void;
|
|
99
|
-
protected deleteContent(contentKey: string): void;
|
|
100
|
-
constructor(data: JunctionSchema<ASide, BSide> & Partial<JunctionEntries<Content>>, config?: JunctionAdvancedConfiguration<Content>);
|
|
101
|
-
toJSON(): JunctionJSON<ASide, BSide, Content>;
|
|
102
|
-
set(a: string, ...rest: Content extends null ? [b: string] : [b: string, content: Content]): this;
|
|
103
|
-
set(relation: {
|
|
104
|
-
[Key in ASide | BSide]: string;
|
|
105
|
-
}, ...rest: Content extends null ? [] | [b?: undefined] : [content: Content]): this;
|
|
106
|
-
delete(a: string, b?: string): this;
|
|
107
|
-
delete(relation: Record<ASide | BSide, string> | Record<ASide, string> | Record<BSide, string>, b?: undefined): this;
|
|
108
|
-
getRelatedKey(key: string): string | undefined;
|
|
109
|
-
replaceRelations(a: string, relations: Content extends null ? string[] : Record<string, Content>, config?: {
|
|
110
|
-
reckless: boolean;
|
|
111
|
-
}): this;
|
|
112
|
-
getContent(a: string, b: string): Content | undefined;
|
|
113
|
-
getRelationEntries(input: Record<ASide, string> | Record<BSide, string>): [string, Content][];
|
|
114
|
-
has(a: string, b?: string): boolean;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
42
|
declare const usersInThisRoomIndex: MutableAtomToken<SetRTX<string>, SetRTXJson<string>>;
|
|
118
43
|
declare const roomIndex: MutableAtomToken<SetRTX<string>, SetRTXJson<string>>;
|
|
119
44
|
type UserInRoomMeta = {
|
|
120
45
|
enteredAtEpoch: number;
|
|
121
46
|
};
|
|
122
47
|
declare const DEFAULT_USER_IN_ROOM_META: UserInRoomMeta;
|
|
123
|
-
declare const usersInRooms:
|
|
124
|
-
readonly relations: Junction<"room", "user", UserInRoomMeta>;
|
|
125
|
-
readonly states: {
|
|
126
|
-
readonly roomEntryOfUser: atom_io.ReadonlySelectorFamily<[string, UserInRoomMeta] | null, string>;
|
|
127
|
-
} & {
|
|
128
|
-
readonly userEntriesOfRoom: atom_io.ReadonlySelectorFamily<[string, UserInRoomMeta][], string>;
|
|
129
|
-
} & {
|
|
130
|
-
readonly roomKeyOfUser: atom_io.ReadonlySelectorFamily<string | null, string>;
|
|
131
|
-
} & {
|
|
132
|
-
readonly userKeysOfRoom: atom_io.ReadonlySelectorFamily<string[], string>;
|
|
133
|
-
};
|
|
134
|
-
readonly in: (store: atom_io_internal.Store) => atom_io_data.Join<"room", "user", "1:n", UserInRoomMeta>;
|
|
135
|
-
readonly transact: (transactors: Readonly<{
|
|
136
|
-
get: <S>(state: atom_io.ReadonlySelectorToken<S> | atom_io.WritableToken<S>) => S;
|
|
137
|
-
set: <S_1, New extends S_1>(state: atom_io.WritableToken<S_1>, newValue: New | ((oldValue: S_1) => New)) => void;
|
|
138
|
-
find: typeof atom_io.findState;
|
|
139
|
-
}>, run: (join: atom_io_data.Join<"room", "user", "1:n", UserInRoomMeta>) => void) => void;
|
|
140
|
-
readonly core: {
|
|
141
|
-
readonly findRelatedKeysState: atom_io.MutableAtomFamily<SetRTX<string>, SetRTXJson<string>, string>;
|
|
142
|
-
};
|
|
143
|
-
};
|
|
48
|
+
declare const usersInRooms: atom_io_data.JoinToken<"room", "user", "1:n", UserInRoomMeta>;
|
|
144
49
|
declare const usersInMyRoomView: atom_io.ReadonlySelectorFamilyTokenWithCall<MutableAtomToken<SetRTX<string>, SetRTXJson<string>>[], string>;
|
|
145
50
|
|
|
146
51
|
export { type ContinuityOptions, type ContinuityToken, DEFAULT_USER_IN_ROOM_META, InvariantMap, type PerspectiveToken, SyncGroup, type UserInRoomMeta, continuity, roomIndex, usersInMyRoomView, usersInRooms, usersInThisRoomIndex };
|
package/realtime/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import '../../dist/chunk-U2IICNHQ.js';
|
|
2
2
|
import { assignTransactionToContinuity, IMPLICIT, setEpochNumberOfContinuity, getUpdateToken } from 'atom.io/internal';
|
|
3
3
|
import { atom, selectorFamily } from 'atom.io';
|
|
4
|
-
import { join } from 'atom.io/data';
|
|
4
|
+
import { join, getInternalRelations } from 'atom.io/data';
|
|
5
5
|
import { SetRTX } from 'atom.io/transceivers/set-rtx';
|
|
6
6
|
|
|
7
7
|
var InvariantMap = class extends Map {
|
|
@@ -101,8 +101,10 @@ var usersInRooms = join(
|
|
|
101
101
|
);
|
|
102
102
|
var usersInMyRoomView = selectorFamily({
|
|
103
103
|
key: `usersInMyRoomView`,
|
|
104
|
-
get: (
|
|
105
|
-
|
|
104
|
+
get: (myUsername) => ({ find }) => {
|
|
105
|
+
const usersInRoomsAtoms = getInternalRelations(usersInRooms);
|
|
106
|
+
const myRoomIndex = find(usersInRoomsAtoms, myUsername);
|
|
107
|
+
return [myRoomIndex];
|
|
106
108
|
}
|
|
107
109
|
});
|
|
108
110
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MutableAtomToken } from "atom.io"
|
|
2
2
|
import { atom, selectorFamily } from "atom.io"
|
|
3
|
-
import { join } from "atom.io/data"
|
|
3
|
+
import { getInternalRelations, join } from "atom.io/data"
|
|
4
4
|
import type { SetRTXJson } from "atom.io/transceivers/set-rtx"
|
|
5
5
|
import { SetRTX } from "atom.io/transceivers/set-rtx"
|
|
6
6
|
|
|
@@ -41,8 +41,10 @@ export const usersInMyRoomView = selectorFamily<
|
|
|
41
41
|
>({
|
|
42
42
|
key: `usersInMyRoomView`,
|
|
43
43
|
get:
|
|
44
|
-
(
|
|
44
|
+
(myUsername) =>
|
|
45
45
|
({ find }) => {
|
|
46
|
-
|
|
46
|
+
const usersInRoomsAtoms = getInternalRelations(usersInRooms)
|
|
47
|
+
const myRoomIndex = find(usersInRoomsAtoms, myUsername)
|
|
48
|
+
return [myRoomIndex]
|
|
47
49
|
},
|
|
48
50
|
})
|