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
|
@@ -5,8 +5,8 @@ var internal = require('atom.io/internal');
|
|
|
5
5
|
var setRtx = require('atom.io/transceivers/set-rtx');
|
|
6
6
|
var AtomIO = require('atom.io');
|
|
7
7
|
var realtime = require('atom.io/realtime');
|
|
8
|
-
var child_process = require('child_process');
|
|
9
8
|
var data = require('atom.io/data');
|
|
9
|
+
var child_process = require('child_process');
|
|
10
10
|
|
|
11
11
|
function _interopNamespace(e) {
|
|
12
12
|
if (e && e.__esModule) return e;
|
|
@@ -216,8 +216,8 @@ var SubjectSocket = class extends CustomSocket {
|
|
|
216
216
|
});
|
|
217
217
|
}
|
|
218
218
|
dispose() {
|
|
219
|
-
for (const
|
|
220
|
-
|
|
219
|
+
for (const dispose2 of this.disposalFunctions) {
|
|
220
|
+
dispose2();
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
};
|
|
@@ -338,6 +338,138 @@ var ParentSocket = class extends CustomSocket {
|
|
|
338
338
|
this.relayServices.push(attachServices);
|
|
339
339
|
}
|
|
340
340
|
};
|
|
341
|
+
function capitalize(string) {
|
|
342
|
+
return string[0].toUpperCase() + string.slice(1);
|
|
343
|
+
}
|
|
344
|
+
function getJoinMap(store) {
|
|
345
|
+
if (`joins` in store && store.joins instanceof Map) {
|
|
346
|
+
return store.joins;
|
|
347
|
+
}
|
|
348
|
+
const joins = /* @__PURE__ */ new Map();
|
|
349
|
+
store.joins = joins;
|
|
350
|
+
return joins;
|
|
351
|
+
}
|
|
352
|
+
function getJoin(token, store) {
|
|
353
|
+
var _a;
|
|
354
|
+
const joinMap = getJoinMap(store);
|
|
355
|
+
let join2 = joinMap.get(token.key);
|
|
356
|
+
if (join2 === void 0) {
|
|
357
|
+
const rootJoinMap = getJoinMap(internal.IMPLICIT.STORE);
|
|
358
|
+
join2 = (_a = rootJoinMap.get(token.key)) == null ? void 0 : _a.in(store);
|
|
359
|
+
if (join2 === void 0) {
|
|
360
|
+
throw new Error(
|
|
361
|
+
`Join "${token.key}" not found in store "${store.config.name}"`
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
joinMap.set(token.key, join2);
|
|
365
|
+
}
|
|
366
|
+
return join2;
|
|
367
|
+
}
|
|
368
|
+
function findRelationsInStore(token, key, store) {
|
|
369
|
+
const join2 = getJoin(token, store);
|
|
370
|
+
let relations;
|
|
371
|
+
switch (token.cardinality) {
|
|
372
|
+
case `1:1`: {
|
|
373
|
+
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
374
|
+
const keyBA = `${token.b}KeyOf${capitalize(token.a)}`;
|
|
375
|
+
relations = {
|
|
376
|
+
get [keyAB]() {
|
|
377
|
+
const familyAB = join2.states[keyAB];
|
|
378
|
+
const state = internal.findInStore(familyAB, key, store);
|
|
379
|
+
return state;
|
|
380
|
+
},
|
|
381
|
+
get [keyBA]() {
|
|
382
|
+
const familyBA = join2.states[keyBA];
|
|
383
|
+
const state = internal.findInStore(familyBA, key, store);
|
|
384
|
+
return state;
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
|
|
388
|
+
if (entryAB in join2.states) {
|
|
389
|
+
const entryBA = `${token.b}EntryOf${capitalize(token.a)}`;
|
|
390
|
+
Object.assign(relations, {
|
|
391
|
+
get [entryAB]() {
|
|
392
|
+
const familyAB = join2.states[entryAB];
|
|
393
|
+
const state = internal.findInStore(familyAB, key, store);
|
|
394
|
+
return state;
|
|
395
|
+
},
|
|
396
|
+
get [entryBA]() {
|
|
397
|
+
const familyBA = join2.states[entryBA];
|
|
398
|
+
const state = internal.findInStore(familyBA, key, store);
|
|
399
|
+
return state;
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
case `1:n`: {
|
|
406
|
+
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
407
|
+
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
408
|
+
relations = {
|
|
409
|
+
get [keyAB]() {
|
|
410
|
+
const familyAB = join2.states[keyAB];
|
|
411
|
+
const state = internal.findInStore(familyAB, key, store);
|
|
412
|
+
return state;
|
|
413
|
+
},
|
|
414
|
+
get [keysBA]() {
|
|
415
|
+
const familyBA = join2.states[keysBA];
|
|
416
|
+
const state = internal.findInStore(familyBA, key, store);
|
|
417
|
+
return state;
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
|
|
421
|
+
if (entryAB in join2.states) {
|
|
422
|
+
const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
|
|
423
|
+
Object.assign(relations, {
|
|
424
|
+
get [entryAB]() {
|
|
425
|
+
const familyAB = join2.states[entryAB];
|
|
426
|
+
const state = internal.findInStore(familyAB, key, store);
|
|
427
|
+
return state;
|
|
428
|
+
},
|
|
429
|
+
get [entriesBA]() {
|
|
430
|
+
const familyBA = join2.states[entriesBA];
|
|
431
|
+
const state = internal.findInStore(familyBA, key, store);
|
|
432
|
+
return state;
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
case `n:n`: {
|
|
439
|
+
const keysAB = `${token.a}KeysOf${capitalize(token.b)}`;
|
|
440
|
+
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
441
|
+
relations = {
|
|
442
|
+
get [keysAB]() {
|
|
443
|
+
const familyAB = join2.states[keysAB];
|
|
444
|
+
const state = internal.findInStore(familyAB, key, store);
|
|
445
|
+
return state;
|
|
446
|
+
},
|
|
447
|
+
get [keysBA]() {
|
|
448
|
+
const familyBA = join2.states[keysBA];
|
|
449
|
+
const state = internal.findInStore(familyBA, key, store);
|
|
450
|
+
return state;
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`;
|
|
454
|
+
if (entriesAB in join2.states) {
|
|
455
|
+
const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
|
|
456
|
+
Object.assign(relations, {
|
|
457
|
+
get [entriesAB]() {
|
|
458
|
+
const familyAB = join2.states[entriesAB];
|
|
459
|
+
const state = internal.findInStore(familyAB, key, store);
|
|
460
|
+
return state;
|
|
461
|
+
},
|
|
462
|
+
get [entriesBA]() {
|
|
463
|
+
const familyBA = join2.states[entriesBA];
|
|
464
|
+
const state = internal.findInStore(familyBA, key, store);
|
|
465
|
+
return state;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return relations;
|
|
472
|
+
}
|
|
341
473
|
AtomIO.selectorFamily({
|
|
342
474
|
key: `perspectiveRedactor`,
|
|
343
475
|
get: ({ userId, syncGroupKey }) => ({ get, find }) => {
|
|
@@ -442,26 +574,38 @@ var joinRoomTX = AtomIO__namespace.transaction({
|
|
|
442
574
|
key: `joinRoom`,
|
|
443
575
|
do: (transactors, roomId, userId, enteredAtEpoch) => {
|
|
444
576
|
const meta = { enteredAtEpoch };
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
577
|
+
data.editRelationsInStore(
|
|
578
|
+
realtime.usersInRooms,
|
|
579
|
+
(relations) => {
|
|
580
|
+
relations.set({ room: roomId, user: userId }, meta);
|
|
581
|
+
},
|
|
582
|
+
transactors.env().store
|
|
583
|
+
);
|
|
448
584
|
return meta;
|
|
449
585
|
}
|
|
450
586
|
});
|
|
451
587
|
var leaveRoomTX = AtomIO__namespace.transaction({
|
|
452
588
|
key: `leaveRoom`,
|
|
453
589
|
do: (transactors, roomId, userId) => {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
590
|
+
data.editRelationsInStore(
|
|
591
|
+
realtime.usersInRooms,
|
|
592
|
+
(relations) => {
|
|
593
|
+
relations.delete({ room: roomId, user: userId });
|
|
594
|
+
},
|
|
595
|
+
transactors.env().store
|
|
596
|
+
);
|
|
457
597
|
}
|
|
458
598
|
});
|
|
459
599
|
var destroyRoomTX = AtomIO__namespace.transaction({
|
|
460
600
|
key: `destroyRoom`,
|
|
461
601
|
do: (transactors, roomId) => {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
602
|
+
data.editRelationsInStore(
|
|
603
|
+
realtime.usersInRooms,
|
|
604
|
+
(relations) => {
|
|
605
|
+
relations.delete({ room: roomId });
|
|
606
|
+
},
|
|
607
|
+
transactors.env().store
|
|
608
|
+
);
|
|
465
609
|
transactors.set(realtime.roomIndex, (s) => (s.delete(roomId), s));
|
|
466
610
|
}
|
|
467
611
|
});
|
|
@@ -522,11 +666,11 @@ function realtimeContinuitySynchronizer({
|
|
|
522
666
|
return function synchronizer(continuity) {
|
|
523
667
|
let socket = initialSocket;
|
|
524
668
|
const continuityKey = continuity.key;
|
|
525
|
-
const userKeyState =
|
|
526
|
-
usersOfSockets
|
|
669
|
+
const userKeyState = findRelationsInStore(
|
|
670
|
+
usersOfSockets,
|
|
527
671
|
socket.id,
|
|
528
672
|
store
|
|
529
|
-
);
|
|
673
|
+
).userKeyOfSocket;
|
|
530
674
|
const userKey = internal.getFromStore(userKeyState, store);
|
|
531
675
|
if (!userKey) {
|
|
532
676
|
store.logger.error(
|
|
@@ -538,11 +682,11 @@ function realtimeContinuitySynchronizer({
|
|
|
538
682
|
return () => {
|
|
539
683
|
};
|
|
540
684
|
}
|
|
541
|
-
const socketKeyState =
|
|
542
|
-
usersOfSockets
|
|
685
|
+
const socketKeyState = findRelationsInStore(
|
|
686
|
+
usersOfSockets,
|
|
543
687
|
userKey,
|
|
544
688
|
store
|
|
545
|
-
);
|
|
689
|
+
).socketKeyOfUser;
|
|
546
690
|
internal.subscribeToState(
|
|
547
691
|
socketKeyState,
|
|
548
692
|
({ newValue: newSocketKey }) => {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as atom_io_internal from 'atom.io/internal';
|
|
2
1
|
import { Subject, Transceiver, Store } from 'atom.io/internal';
|
|
3
2
|
import { Json, Stringified, JsonIO } from 'atom.io/json';
|
|
4
3
|
import { ChildProcessWithoutNullStreams } from 'child_process';
|
|
@@ -104,99 +103,10 @@ declare const actionOcclusionAtoms: AtomIO.RegularAtomFamilyTokenWithCall<{
|
|
|
104
103
|
}, string>;
|
|
105
104
|
declare const userUnacknowledgedQueues: AtomIO.RegularAtomFamilyTokenWithCall<Pick<TransactionUpdate<any>, "key" | "epoch" | "id" | "updates" | "output">[], string>;
|
|
106
105
|
|
|
107
|
-
type primitive = boolean | number | string | null;
|
|
108
|
-
|
|
109
|
-
type Serializable = primitive | Readonly<{
|
|
110
|
-
[key: string]: Serializable;
|
|
111
|
-
}> | ReadonlyArray<Serializable>;
|
|
112
|
-
type Object$1<Key extends string = string, Value extends Serializable = Serializable> = Record<Key, Value>;
|
|
113
|
-
|
|
114
|
-
type Refinement<Unrefined, Refined extends Unrefined> = (value: Unrefined) => value is Refined;
|
|
115
|
-
type Cardinality = `1:1` | `1:n` | `n:n`;
|
|
116
|
-
|
|
117
|
-
interface JunctionEntries<Content extends Object$1 | null> extends Object$1 {
|
|
118
|
-
readonly relations: [string, string[]][];
|
|
119
|
-
readonly contents: [string, Content][];
|
|
120
|
-
}
|
|
121
|
-
interface JunctionSchema<ASide extends string, BSide extends string> extends Object$1 {
|
|
122
|
-
readonly between: [a: ASide, b: BSide];
|
|
123
|
-
readonly cardinality: Cardinality;
|
|
124
|
-
}
|
|
125
|
-
type BaseExternalStoreConfiguration = {
|
|
126
|
-
addRelation: (a: string, b: string) => void;
|
|
127
|
-
deleteRelation: (a: string, b: string) => void;
|
|
128
|
-
replaceRelationsSafely: (a: string, bs: string[]) => void;
|
|
129
|
-
replaceRelationsUnsafely: (a: string, bs: string[]) => void;
|
|
130
|
-
getRelatedKeys: (key: string) => Set<string> | undefined;
|
|
131
|
-
has: (a: string, b?: string) => boolean;
|
|
132
|
-
};
|
|
133
|
-
type ExternalStoreWithContentConfiguration<Content extends Object$1> = {
|
|
134
|
-
getContent: (contentKey: string) => Content | undefined;
|
|
135
|
-
setContent: (contentKey: string, content: Content) => void;
|
|
136
|
-
deleteContent: (contentKey: string) => void;
|
|
137
|
-
};
|
|
138
|
-
type Empty<Obj extends object> = {
|
|
139
|
-
[Key in keyof Obj]?: undefined;
|
|
140
|
-
};
|
|
141
|
-
type ExternalStoreConfiguration<Content extends Object$1 | null> = Content extends Object$1 ? BaseExternalStoreConfiguration & ExternalStoreWithContentConfiguration<Content> : BaseExternalStoreConfiguration & Empty<ExternalStoreWithContentConfiguration<Object$1>>;
|
|
142
|
-
type JunctionAdvancedConfiguration<Content extends Object$1 | null> = {
|
|
143
|
-
externalStore?: ExternalStoreConfiguration<Content>;
|
|
144
|
-
isContent?: Refinement<unknown, Content>;
|
|
145
|
-
makeContentKey?: (a: string, b: string) => string;
|
|
146
|
-
};
|
|
147
|
-
type JunctionJSON<ASide extends string, BSide extends string, Content extends Object$1 | null> = JunctionEntries<Content> & JunctionSchema<ASide, BSide>;
|
|
148
|
-
declare class Junction<const ASide extends string, const BSide extends string, const Content extends Object$1 | null = null> {
|
|
149
|
-
readonly a: ASide;
|
|
150
|
-
readonly b: BSide;
|
|
151
|
-
readonly cardinality: Cardinality;
|
|
152
|
-
readonly relations: Map<string, Set<string>>;
|
|
153
|
-
readonly contents: Map<string, Content>;
|
|
154
|
-
isContent: Refinement<unknown, Content> | null;
|
|
155
|
-
makeContentKey: (a: string, b: string) => string;
|
|
156
|
-
getRelatedKeys(key: string): Set<string> | undefined;
|
|
157
|
-
protected addRelation(a: string, b: string): void;
|
|
158
|
-
protected deleteRelation(a: string, b: string): void;
|
|
159
|
-
protected replaceRelationsUnsafely(a: string, bs: string[]): void;
|
|
160
|
-
protected replaceRelationsSafely(a: string, bs: string[]): void;
|
|
161
|
-
protected getContentInternal(contentKey: string): Content | undefined;
|
|
162
|
-
protected setContent(contentKey: string, content: Content): void;
|
|
163
|
-
protected deleteContent(contentKey: string): void;
|
|
164
|
-
constructor(data: JunctionSchema<ASide, BSide> & Partial<JunctionEntries<Content>>, config?: JunctionAdvancedConfiguration<Content>);
|
|
165
|
-
toJSON(): JunctionJSON<ASide, BSide, Content>;
|
|
166
|
-
set(a: string, ...rest: Content extends null ? [b: string] : [b: string, content: Content]): this;
|
|
167
|
-
set(relation: {
|
|
168
|
-
[Key in ASide | BSide]: string;
|
|
169
|
-
}, ...rest: Content extends null ? [] | [b?: undefined] : [content: Content]): this;
|
|
170
|
-
delete(a: string, b?: string): this;
|
|
171
|
-
delete(relation: Record<ASide | BSide, string> | Record<ASide, string> | Record<BSide, string>, b?: undefined): this;
|
|
172
|
-
getRelatedKey(key: string): string | undefined;
|
|
173
|
-
replaceRelations(a: string, relations: Content extends null ? string[] : Record<string, Content>, config?: {
|
|
174
|
-
reckless: boolean;
|
|
175
|
-
}): this;
|
|
176
|
-
getContent(a: string, b: string): Content | undefined;
|
|
177
|
-
getRelationEntries(input: Record<ASide, string> | Record<BSide, string>): [string, Content][];
|
|
178
|
-
has(a: string, b?: string): boolean;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
106
|
declare const socketAtoms: AtomIO.RegularAtomFamilyTokenWithCall<Socket | null, string>;
|
|
182
107
|
declare const socketIndex: AtomIO.MutableAtomToken<SetRTX<string>, atom_io_transceivers_set_rtx.SetRTXJson<string>>;
|
|
183
108
|
declare const userIndex: AtomIO.MutableAtomToken<SetRTX<string>, atom_io_transceivers_set_rtx.SetRTXJson<string>>;
|
|
184
|
-
declare const usersOfSockets:
|
|
185
|
-
readonly relations: Junction<"user", "socket", null>;
|
|
186
|
-
readonly states: {
|
|
187
|
-
readonly socketKeyOfUser: AtomIO.ReadonlySelectorFamily<string | null, string>;
|
|
188
|
-
readonly userKeyOfSocket: AtomIO.ReadonlySelectorFamily<string | null, string>;
|
|
189
|
-
};
|
|
190
|
-
readonly in: (store: atom_io_internal.Store) => atom_io_data.Join<"user", "socket", "1:1", null>;
|
|
191
|
-
readonly transact: (transactors: Readonly<{
|
|
192
|
-
get: <S>(state: AtomIO.ReadonlySelectorToken<S> | AtomIO.WritableToken<S>) => S;
|
|
193
|
-
set: <S_1, New extends S_1>(state: AtomIO.WritableToken<S_1>, newValue: New | ((oldValue: S_1) => New)) => void;
|
|
194
|
-
find: typeof AtomIO.findState;
|
|
195
|
-
}>, run: (join: atom_io_data.Join<"user", "socket", "1:1", null>) => void) => void;
|
|
196
|
-
readonly core: {
|
|
197
|
-
readonly findRelatedKeysState: AtomIO.MutableAtomFamily<SetRTX<string>, atom_io_transceivers_set_rtx.SetRTXJson<string>, string>;
|
|
198
|
-
};
|
|
199
|
-
};
|
|
109
|
+
declare const usersOfSockets: atom_io_data.JoinToken<"user", "socket", "1:1", null>;
|
|
200
110
|
|
|
201
111
|
type StateProvider = ReturnType<typeof realtimeStateProvider>;
|
|
202
112
|
declare function realtimeStateProvider({ socket, store, }: ServerConfig): <J extends Json.Serializable>(token: AtomIO.WritableToken<J>) => () => void;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import { findRelationsInStore } from '../../dist/chunk-7ZR244C2.js';
|
|
2
|
+
import '../../dist/chunk-WX2NCOZR.js';
|
|
1
3
|
import { __spreadProps, __spreadValues } from '../../dist/chunk-U2IICNHQ.js';
|
|
2
4
|
import { parseJson, stringifyJson } from 'atom.io/json';
|
|
3
|
-
import { getUpdateToken, IMPLICIT, Subject,
|
|
5
|
+
import { getUpdateToken, IMPLICIT, Subject, getFromStore, subscribeToState, findInStore, getJsonToken, isRootStore, subscribeToTransaction, actUponStore, setIntoStore } from 'atom.io/internal';
|
|
4
6
|
import { SetRTX } from 'atom.io/transceivers/set-rtx';
|
|
5
7
|
import * as AtomIO from 'atom.io';
|
|
6
8
|
import { selectorFamily, atomFamily, atom } from 'atom.io';
|
|
7
9
|
import { SyncGroup, roomIndex, usersInRooms } from 'atom.io/realtime';
|
|
10
|
+
import { editRelationsInStore, join } from 'atom.io/data';
|
|
8
11
|
import { spawn } from 'child_process';
|
|
9
|
-
import { join } from 'atom.io/data';
|
|
10
12
|
|
|
11
13
|
// realtime-server/src/ipc-sockets/custom-socket.ts
|
|
12
14
|
var CustomSocket = class {
|
|
@@ -402,26 +404,38 @@ var joinRoomTX = AtomIO.transaction({
|
|
|
402
404
|
key: `joinRoom`,
|
|
403
405
|
do: (transactors, roomId, userId, enteredAtEpoch) => {
|
|
404
406
|
const meta = { enteredAtEpoch };
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
407
|
+
editRelationsInStore(
|
|
408
|
+
usersInRooms,
|
|
409
|
+
(relations) => {
|
|
410
|
+
relations.set({ room: roomId, user: userId }, meta);
|
|
411
|
+
},
|
|
412
|
+
transactors.env().store
|
|
413
|
+
);
|
|
408
414
|
return meta;
|
|
409
415
|
}
|
|
410
416
|
});
|
|
411
417
|
var leaveRoomTX = AtomIO.transaction({
|
|
412
418
|
key: `leaveRoom`,
|
|
413
419
|
do: (transactors, roomId, userId) => {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
420
|
+
editRelationsInStore(
|
|
421
|
+
usersInRooms,
|
|
422
|
+
(relations) => {
|
|
423
|
+
relations.delete({ room: roomId, user: userId });
|
|
424
|
+
},
|
|
425
|
+
transactors.env().store
|
|
426
|
+
);
|
|
417
427
|
}
|
|
418
428
|
});
|
|
419
429
|
var destroyRoomTX = AtomIO.transaction({
|
|
420
430
|
key: `destroyRoom`,
|
|
421
431
|
do: (transactors, roomId) => {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
432
|
+
editRelationsInStore(
|
|
433
|
+
usersInRooms,
|
|
434
|
+
(relations) => {
|
|
435
|
+
relations.delete({ room: roomId });
|
|
436
|
+
},
|
|
437
|
+
transactors.env().store
|
|
438
|
+
);
|
|
425
439
|
transactors.set(roomIndex, (s) => (s.delete(roomId), s));
|
|
426
440
|
}
|
|
427
441
|
});
|
|
@@ -482,11 +496,11 @@ function realtimeContinuitySynchronizer({
|
|
|
482
496
|
return function synchronizer(continuity) {
|
|
483
497
|
let socket = initialSocket;
|
|
484
498
|
const continuityKey = continuity.key;
|
|
485
|
-
const userKeyState =
|
|
486
|
-
usersOfSockets
|
|
499
|
+
const userKeyState = findRelationsInStore(
|
|
500
|
+
usersOfSockets,
|
|
487
501
|
socket.id,
|
|
488
502
|
store
|
|
489
|
-
);
|
|
503
|
+
).userKeyOfSocket;
|
|
490
504
|
const userKey = getFromStore(userKeyState, store);
|
|
491
505
|
if (!userKey) {
|
|
492
506
|
store.logger.error(
|
|
@@ -498,11 +512,11 @@ function realtimeContinuitySynchronizer({
|
|
|
498
512
|
return () => {
|
|
499
513
|
};
|
|
500
514
|
}
|
|
501
|
-
const socketKeyState =
|
|
502
|
-
usersOfSockets
|
|
515
|
+
const socketKeyState = findRelationsInStore(
|
|
516
|
+
usersOfSockets,
|
|
503
517
|
userKey,
|
|
504
518
|
store
|
|
505
|
-
);
|
|
519
|
+
).socketKeyOfUser;
|
|
506
520
|
subscribeToState(
|
|
507
521
|
socketKeyState,
|
|
508
522
|
({ newValue: newSocketKey }) => {
|
|
@@ -15,6 +15,7 @@ import type { ContinuityToken } from "atom.io/realtime"
|
|
|
15
15
|
import type { ServerConfig, Socket } from "."
|
|
16
16
|
import { socketAtoms, usersOfSockets } from "."
|
|
17
17
|
|
|
18
|
+
import { findRelationsInStore } from "../../data/src/join"
|
|
18
19
|
import {
|
|
19
20
|
redactTransactionUpdateContent,
|
|
20
21
|
userUnacknowledgedQueues,
|
|
@@ -31,11 +32,11 @@ export function realtimeContinuitySynchronizer({
|
|
|
31
32
|
let socket: Socket | null = initialSocket
|
|
32
33
|
|
|
33
34
|
const continuityKey = continuity.key
|
|
34
|
-
const userKeyState =
|
|
35
|
-
usersOfSockets
|
|
35
|
+
const userKeyState = findRelationsInStore(
|
|
36
|
+
usersOfSockets,
|
|
36
37
|
socket.id,
|
|
37
38
|
store,
|
|
38
|
-
)
|
|
39
|
+
).userKeyOfSocket
|
|
39
40
|
const userKey = getFromStore(userKeyState, store)
|
|
40
41
|
if (!userKey) {
|
|
41
42
|
store.logger.error(
|
|
@@ -46,11 +47,12 @@ export function realtimeContinuitySynchronizer({
|
|
|
46
47
|
)
|
|
47
48
|
return () => {}
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
|
|
51
|
+
const socketKeyState = findRelationsInStore(
|
|
52
|
+
usersOfSockets,
|
|
51
53
|
userKey,
|
|
52
54
|
store,
|
|
53
|
-
)
|
|
55
|
+
).socketKeyOfUser
|
|
54
56
|
subscribeToState(
|
|
55
57
|
socketKeyState,
|
|
56
58
|
({ newValue: newSocketKey }) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as AtomIO from "atom.io"
|
|
2
|
-
import type
|
|
2
|
+
import { type Loadable, editRelations, editRelationsInStore } from "atom.io/data"
|
|
3
3
|
import type { UserInRoomMeta } from "atom.io/realtime"
|
|
4
4
|
import { roomIndex, usersInRooms } from "atom.io/realtime"
|
|
5
5
|
|
|
@@ -33,9 +33,13 @@ export const joinRoomTX = AtomIO.transaction<
|
|
|
33
33
|
key: `joinRoom`,
|
|
34
34
|
do: (transactors, roomId, userId, enteredAtEpoch) => {
|
|
35
35
|
const meta = { enteredAtEpoch }
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
editRelationsInStore(
|
|
37
|
+
usersInRooms,
|
|
38
|
+
(relations) => {
|
|
39
|
+
relations.set({ room: roomId, user: userId }, meta)
|
|
40
|
+
},
|
|
41
|
+
transactors.env().store,
|
|
42
|
+
)
|
|
39
43
|
return meta
|
|
40
44
|
},
|
|
41
45
|
})
|
|
@@ -46,9 +50,13 @@ export const leaveRoomTX = AtomIO.transaction<
|
|
|
46
50
|
>({
|
|
47
51
|
key: `leaveRoom`,
|
|
48
52
|
do: (transactors, roomId, userId) => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
editRelationsInStore(
|
|
54
|
+
usersInRooms,
|
|
55
|
+
(relations) => {
|
|
56
|
+
relations.delete({ room: roomId, user: userId })
|
|
57
|
+
},
|
|
58
|
+
transactors.env().store,
|
|
59
|
+
)
|
|
52
60
|
},
|
|
53
61
|
})
|
|
54
62
|
export type LeaveRoomIO = AtomIO.TransactionIO<typeof leaveRoomTX>
|
|
@@ -56,9 +64,13 @@ export type LeaveRoomIO = AtomIO.TransactionIO<typeof leaveRoomTX>
|
|
|
56
64
|
export const destroyRoomTX = AtomIO.transaction<(roomId: string) => void>({
|
|
57
65
|
key: `destroyRoom`,
|
|
58
66
|
do: (transactors, roomId) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
editRelationsInStore(
|
|
68
|
+
usersInRooms,
|
|
69
|
+
(relations) => {
|
|
70
|
+
relations.delete({ room: roomId })
|
|
71
|
+
},
|
|
72
|
+
transactors.env().store,
|
|
73
|
+
)
|
|
62
74
|
transactors.set(roomIndex, (s) => (s.delete(roomId), s))
|
|
63
75
|
},
|
|
64
76
|
})
|
|
@@ -11,6 +11,7 @@ var RTS = require('atom.io/realtime-server');
|
|
|
11
11
|
var Happy = require('happy-dom');
|
|
12
12
|
var SocketIO = require('socket.io');
|
|
13
13
|
var socket_ioClient = require('socket.io-client');
|
|
14
|
+
require('atom.io/transceivers/set-rtx');
|
|
14
15
|
var jsxRuntime = require('react/jsx-runtime');
|
|
15
16
|
|
|
16
17
|
function _interopNamespace(e) {
|
|
@@ -62,6 +63,42 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
|
62
63
|
|
|
63
64
|
// ../anvl/src/object/entries.ts
|
|
64
65
|
var recordToEntries = (obj) => Object.entries(obj);
|
|
66
|
+
function getJoinMap(store) {
|
|
67
|
+
if (`joins` in store && store.joins instanceof Map) {
|
|
68
|
+
return store.joins;
|
|
69
|
+
}
|
|
70
|
+
const joins = /* @__PURE__ */ new Map();
|
|
71
|
+
store.joins = joins;
|
|
72
|
+
return joins;
|
|
73
|
+
}
|
|
74
|
+
function getJoin(token, store) {
|
|
75
|
+
var _a;
|
|
76
|
+
const joinMap = getJoinMap(store);
|
|
77
|
+
let join = joinMap.get(token.key);
|
|
78
|
+
if (join === void 0) {
|
|
79
|
+
const rootJoinMap = getJoinMap(internal.IMPLICIT.STORE);
|
|
80
|
+
join = (_a = rootJoinMap.get(token.key)) == null ? void 0 : _a.in(store);
|
|
81
|
+
if (join === void 0) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Join "${token.key}" not found in store "${store.config.name}"`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
joinMap.set(token.key, join);
|
|
87
|
+
}
|
|
88
|
+
return join;
|
|
89
|
+
}
|
|
90
|
+
function editRelationsInStore(token, change, store) {
|
|
91
|
+
const join = getJoin(token, store);
|
|
92
|
+
const target = internal.newest(store);
|
|
93
|
+
if (internal.isChildStore(target)) {
|
|
94
|
+
const { transactors } = target.transactionMeta;
|
|
95
|
+
join.transact(transactors, ({ relations }) => {
|
|
96
|
+
change(relations);
|
|
97
|
+
});
|
|
98
|
+
} else {
|
|
99
|
+
change(join.relations);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
65
102
|
|
|
66
103
|
// __unstable__/web-effects/src/storage.ts
|
|
67
104
|
var persistAtom = (storage) => ({ stringify, parse }) => (key) => ({ setSelf, onSet }) => {
|
|
@@ -117,8 +154,13 @@ var setupRealtimeTestServer = (options) => {
|
|
|
117
154
|
if (token === `test` && socket.id) {
|
|
118
155
|
const socketState = internal.findInStore(RTS__namespace.socketAtoms, socket.id, silo.store);
|
|
119
156
|
internal.setIntoStore(socketState, socket, silo.store);
|
|
120
|
-
|
|
121
|
-
|
|
157
|
+
editRelationsInStore(
|
|
158
|
+
RTS__namespace.usersOfSockets,
|
|
159
|
+
(relations) => {
|
|
160
|
+
relations.set(socket.id, username);
|
|
161
|
+
},
|
|
162
|
+
silo.store
|
|
163
|
+
);
|
|
122
164
|
internal.setIntoStore(RTS__namespace.userIndex, (index) => index.add(username), silo.store);
|
|
123
165
|
internal.setIntoStore(RTS__namespace.socketIndex, (index) => index.add(socket.id), silo.store);
|
|
124
166
|
console.log(`${username} connected on ${socket.id}`);
|
|
@@ -130,7 +172,7 @@ var setupRealtimeTestServer = (options) => {
|
|
|
130
172
|
server.on(`connection`, (socket) => {
|
|
131
173
|
options.server({ socket, silo });
|
|
132
174
|
});
|
|
133
|
-
const
|
|
175
|
+
const dispose2 = () => {
|
|
134
176
|
server.close();
|
|
135
177
|
const roomKeys = internal.getFromStore(RT__namespace.roomIndex, silo.store);
|
|
136
178
|
for (const roomKey of roomKeys) {
|
|
@@ -145,7 +187,7 @@ var setupRealtimeTestServer = (options) => {
|
|
|
145
187
|
return {
|
|
146
188
|
name: `SERVER`,
|
|
147
189
|
silo,
|
|
148
|
-
dispose,
|
|
190
|
+
dispose: dispose2,
|
|
149
191
|
port
|
|
150
192
|
};
|
|
151
193
|
};
|
|
@@ -172,12 +214,12 @@ var setupRealtimeTestClient = (options, name, port) => {
|
|
|
172
214
|
}
|
|
173
215
|
);
|
|
174
216
|
const prettyPrint = () => console.log(react.prettyDOM(renderResult.container));
|
|
175
|
-
const
|
|
217
|
+
const dispose2 = () => {
|
|
176
218
|
renderResult.unmount();
|
|
177
219
|
socket.disconnect();
|
|
178
220
|
internal.clearStore(silo.store);
|
|
179
221
|
};
|
|
180
|
-
testClient.dispose =
|
|
222
|
+
testClient.dispose = dispose2;
|
|
181
223
|
return {
|
|
182
224
|
name,
|
|
183
225
|
silo,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { myUsernameState } from '../../dist/chunk-O47EQUM6.js';
|
|
2
|
+
import { editRelationsInStore } from '../../dist/chunk-7ZR244C2.js';
|
|
3
|
+
import '../../dist/chunk-WX2NCOZR.js';
|
|
2
4
|
import { recordToEntries } from '../../dist/chunk-CVBEVTM5.js';
|
|
3
5
|
import '../../dist/chunk-BWWVY5O5.js';
|
|
4
6
|
import { __spreadProps, __spreadValues } from '../../dist/chunk-U2IICNHQ.js';
|
|
@@ -29,8 +31,13 @@ var setupRealtimeTestServer = (options) => {
|
|
|
29
31
|
if (token === `test` && socket.id) {
|
|
30
32
|
const socketState = findInStore(RTS.socketAtoms, socket.id, silo.store);
|
|
31
33
|
setIntoStore(socketState, socket, silo.store);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
editRelationsInStore(
|
|
35
|
+
RTS.usersOfSockets,
|
|
36
|
+
(relations) => {
|
|
37
|
+
relations.set(socket.id, username);
|
|
38
|
+
},
|
|
39
|
+
silo.store
|
|
40
|
+
);
|
|
34
41
|
setIntoStore(RTS.userIndex, (index) => index.add(username), silo.store);
|
|
35
42
|
setIntoStore(RTS.socketIndex, (index) => index.add(socket.id), silo.store);
|
|
36
43
|
console.log(`${username} connected on ${socket.id}`);
|
|
@@ -21,6 +21,7 @@ import type { Socket as ClientSocket } from "socket.io-client"
|
|
|
21
21
|
import { io } from "socket.io-client"
|
|
22
22
|
|
|
23
23
|
import { recordToEntries } from "~/packages/anvl/src/object"
|
|
24
|
+
import { editRelationsInStore } from "../../data/src/join"
|
|
24
25
|
import { myUsernameState } from "../../realtime-client/src/realtime-client-stores"
|
|
25
26
|
|
|
26
27
|
let testNumber = 0
|
|
@@ -87,8 +88,13 @@ export const setupRealtimeTestServer = (
|
|
|
87
88
|
if (token === `test` && socket.id) {
|
|
88
89
|
const socketState = findInStore(RTS.socketAtoms, socket.id, silo.store)
|
|
89
90
|
setIntoStore(socketState, socket, silo.store)
|
|
90
|
-
|
|
91
|
-
|
|
91
|
+
editRelationsInStore(
|
|
92
|
+
RTS.usersOfSockets,
|
|
93
|
+
(relations) => {
|
|
94
|
+
relations.set(socket.id, username)
|
|
95
|
+
},
|
|
96
|
+
silo.store,
|
|
97
|
+
)
|
|
92
98
|
setIntoStore(RTS.userIndex, (index) => index.add(username), silo.store)
|
|
93
99
|
setIntoStore(RTS.socketIndex, (index) => index.add(socket.id), silo.store)
|
|
94
100
|
console.log(`${username} connected on ${socket.id}`)
|