atom.io 0.30.0 → 0.30.1
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 +84 -51
- package/data/dist/index.js +35 -31
- package/data/src/join.ts +240 -134
- package/dist/chunk-ADMEAXYU.js +167 -0
- package/dist/{chunk-7PUUHSXC.js → chunk-SMKF3ZNG.js} +45 -171
- package/dist/index.d.ts +53 -5
- package/dist/index.js +1 -1
- package/internal/dist/index.d.ts +62 -35
- package/internal/dist/index.js +2 -2
- package/internal/src/junction.ts +152 -84
- package/internal/src/molecule/make-molecule-in-store.ts +3 -1
- package/internal/src/molecule/molecule-internal.ts +1 -1
- package/internal/src/mutable/create-mutable-atom-family.ts +2 -2
- package/internal/src/mutable/get-json-family.ts +2 -2
- package/internal/src/store/store.ts +4 -0
- package/internal/src/transaction/index.ts +1 -1
- package/json/dist/index.js +2 -2
- package/package.json +15 -15
- package/realtime/dist/index.d.ts +1 -1
- package/realtime/dist/index.js +3 -1
- package/realtime/src/shared-room-store.ts +2 -0
- package/realtime-server/dist/index.d.ts +13 -4
- package/realtime-server/dist/index.js +4 -2
- package/realtime-server/src/realtime-continuity-synchronizer.ts +2 -2
- package/realtime-server/src/realtime-server-stores/server-user-store.ts +17 -1
- package/realtime-testing/dist/index.d.ts +3 -0
- package/realtime-testing/dist/index.js +11 -4
- package/realtime-testing/src/setup-realtime-test.tsx +12 -4
- package/src/allocate.ts +7 -8
- package/src/index.ts +1 -0
- package/src/molecule.ts +5 -3
- package/dist/chunk-ZKG6ZA4I.js +0 -20
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
StateCreation,
|
|
8
8
|
StateDisposal,
|
|
9
9
|
} from "atom.io"
|
|
10
|
-
import type { Json } from "atom.io/json"
|
|
10
|
+
import type { Canonical, Json } from "atom.io/json"
|
|
11
11
|
import { selectJsonFamily, stringifyJson } from "atom.io/json"
|
|
12
12
|
|
|
13
13
|
import { type MutableAtomFamily, prettyPrintTokenType } from ".."
|
|
@@ -21,7 +21,7 @@ import type { Transceiver } from "./transceiver"
|
|
|
21
21
|
export function createMutableAtomFamily<
|
|
22
22
|
T extends Transceiver<any>,
|
|
23
23
|
J extends Json.Serializable,
|
|
24
|
-
K extends
|
|
24
|
+
K extends Canonical,
|
|
25
25
|
>(
|
|
26
26
|
store: Store,
|
|
27
27
|
options: MutableAtomFamilyOptions<T, J, K>,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MutableAtomFamilyToken } from "atom.io"
|
|
2
|
-
import type { Json } from "atom.io/json"
|
|
2
|
+
import type { Canonical, Json } from "atom.io/json"
|
|
3
3
|
|
|
4
4
|
import type { WritableSelectorFamily } from ".."
|
|
5
5
|
import { newest } from "../lineage"
|
|
@@ -9,7 +9,7 @@ import type { Transceiver } from "./transceiver"
|
|
|
9
9
|
export const getJsonFamily = <
|
|
10
10
|
Core extends Transceiver<Json.Serializable>,
|
|
11
11
|
SerializableCore extends Json.Serializable,
|
|
12
|
-
Key extends
|
|
12
|
+
Key extends Canonical,
|
|
13
13
|
>(
|
|
14
14
|
mutableAtomFamily: MutableAtomFamilyToken<Core, SerializableCore, Key>,
|
|
15
15
|
store: Store,
|
|
@@ -56,7 +56,9 @@ export class Store implements Lineage {
|
|
|
56
56
|
})
|
|
57
57
|
public selectorGraph = new Junction<
|
|
58
58
|
`upstreamSelectorKey`,
|
|
59
|
+
string,
|
|
59
60
|
`downstreamSelectorKey`,
|
|
61
|
+
string,
|
|
60
62
|
{ source: string }
|
|
61
63
|
>(
|
|
62
64
|
{
|
|
@@ -88,7 +90,9 @@ export class Store implements Lineage {
|
|
|
88
90
|
public timelines = new Map<string, Timeline<any>>()
|
|
89
91
|
public timelineTopics = new Junction<
|
|
90
92
|
`timelineKey`,
|
|
93
|
+
string,
|
|
91
94
|
`topicKey`,
|
|
95
|
+
string,
|
|
92
96
|
{ topicType: `atom_family` | `atom` | `molecule_family` | `molecule` }
|
|
93
97
|
>({
|
|
94
98
|
between: [`timelineKey`, `topicKey`],
|
package/json/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createWritableSelectorFamily } from '../../dist/chunk-
|
|
2
|
-
import '../../dist/chunk-
|
|
1
|
+
import { createWritableSelectorFamily } from '../../dist/chunk-SMKF3ZNG.js';
|
|
2
|
+
import '../../dist/chunk-ADMEAXYU.js';
|
|
3
3
|
import '../../dist/chunk-XWL6SNVU.js';
|
|
4
4
|
import { createStandaloneSelector, IMPLICIT, growMoleculeInStore, initFamilyMemberInStore, withdraw, seekInStore } from 'atom.io/internal';
|
|
5
5
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atom.io",
|
|
3
|
-
"version": "0.30.
|
|
3
|
+
"version": "0.30.1",
|
|
4
4
|
"description": "Composable and testable reactive data library.",
|
|
5
5
|
"homepage": "https://atom.io.fyi",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -57,34 +57,34 @@
|
|
|
57
57
|
"@types/estree": "1.0.6",
|
|
58
58
|
"@types/http-proxy": "1.17.15",
|
|
59
59
|
"@types/npmlog": "7.0.0",
|
|
60
|
-
"@types/react": "18.3.
|
|
60
|
+
"@types/react": "18.3.12",
|
|
61
61
|
"@types/tmp": "0.2.6",
|
|
62
|
-
"@typescript-eslint/parser": "8.
|
|
63
|
-
"@typescript-eslint/rule-tester": "8.
|
|
64
|
-
"@vitest/coverage-v8": "2.1.
|
|
65
|
-
"@vitest/ui": "2.1.
|
|
62
|
+
"@typescript-eslint/parser": "8.10.0",
|
|
63
|
+
"@typescript-eslint/rule-tester": "8.10.0",
|
|
64
|
+
"@vitest/coverage-v8": "2.1.3",
|
|
65
|
+
"@vitest/ui": "2.1.3",
|
|
66
66
|
"concurrently": "9.0.1",
|
|
67
|
-
"drizzle-kit": "0.
|
|
68
|
-
"drizzle-orm": "0.
|
|
69
|
-
"eslint": "9.
|
|
70
|
-
"framer-motion": "11.11.
|
|
67
|
+
"drizzle-kit": "0.26.2",
|
|
68
|
+
"drizzle-orm": "0.35.3",
|
|
69
|
+
"eslint": "9.13.0",
|
|
70
|
+
"framer-motion": "11.11.9",
|
|
71
71
|
"happy-dom": "15.7.4",
|
|
72
72
|
"http-proxy": "1.18.1",
|
|
73
73
|
"npmlog": "7.0.1",
|
|
74
74
|
"postgres": "3.4.4",
|
|
75
|
-
"preact": "10.24.
|
|
75
|
+
"preact": "10.24.3",
|
|
76
76
|
"react": "18.3.1",
|
|
77
77
|
"react-dom": "18.3.1",
|
|
78
|
-
"react-router-dom": "6.
|
|
78
|
+
"react-router-dom": "6.27.0",
|
|
79
79
|
"socket.io": "4.8.0",
|
|
80
80
|
"socket.io-client": "4.8.0",
|
|
81
81
|
"tmp": "0.2.3",
|
|
82
82
|
"tsup": "8.3.0",
|
|
83
83
|
"tsx": "4.19.1",
|
|
84
|
-
"typescript": "5.6.
|
|
85
|
-
"vite": "5.4.
|
|
84
|
+
"typescript": "5.6.3",
|
|
85
|
+
"vite": "5.4.10",
|
|
86
86
|
"vite-tsconfig-paths": "5.0.1",
|
|
87
|
-
"vitest": "2.1.
|
|
87
|
+
"vitest": "2.1.3",
|
|
88
88
|
"zod": "3.23.8"
|
|
89
89
|
},
|
|
90
90
|
"main": "dist/index.js",
|
package/realtime/dist/index.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ type UserInRoomMeta = {
|
|
|
45
45
|
enteredAtEpoch: number;
|
|
46
46
|
};
|
|
47
47
|
declare const DEFAULT_USER_IN_ROOM_META: UserInRoomMeta;
|
|
48
|
-
declare const usersInRooms: atom_io_data.JoinToken<"room", "user", "1:n", UserInRoomMeta>;
|
|
48
|
+
declare const usersInRooms: atom_io_data.JoinToken<"room", string, "user", string, "1:n", UserInRoomMeta>;
|
|
49
49
|
declare const usersInMyRoomView: atom_io.ReadonlySelectorFamilyToken<MutableAtomToken<SetRTX<string>, SetRTXJson<string>>[], string>;
|
|
50
50
|
|
|
51
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
|
@@ -90,7 +90,9 @@ var usersInRooms = join(
|
|
|
90
90
|
{
|
|
91
91
|
key: `usersInRooms`,
|
|
92
92
|
between: [`room`, `user`],
|
|
93
|
-
cardinality: `1:n
|
|
93
|
+
cardinality: `1:n`,
|
|
94
|
+
isAType: (input) => typeof input === `string`,
|
|
95
|
+
isBType: (input) => typeof input === `string`
|
|
94
96
|
},
|
|
95
97
|
DEFAULT_USER_IN_ROOM_META
|
|
96
98
|
);
|
|
@@ -31,6 +31,8 @@ export const usersInRooms = join(
|
|
|
31
31
|
key: `usersInRooms`,
|
|
32
32
|
between: [`room`, `user`],
|
|
33
33
|
cardinality: `1:n`,
|
|
34
|
+
isAType: (input): input is string => typeof input === `string`,
|
|
35
|
+
isBType: (input): input is string => typeof input === `string`,
|
|
34
36
|
},
|
|
35
37
|
DEFAULT_USER_IN_ROOM_META,
|
|
36
38
|
)
|
|
@@ -2,7 +2,7 @@ import { Subject, Transceiver, Store } from 'atom.io/internal';
|
|
|
2
2
|
import { Json, stringified, JsonIO, Canonical } from 'atom.io/json';
|
|
3
3
|
import { ChildProcessWithoutNullStreams } from 'node:child_process';
|
|
4
4
|
import * as AtomIO from 'atom.io';
|
|
5
|
-
import { TransactionUpdateContent, TransactionUpdate, WritableToken } from 'atom.io';
|
|
5
|
+
import { TransactionUpdateContent, TransactionUpdate, Hierarchy, WritableToken } from 'atom.io';
|
|
6
6
|
import { ContinuityToken, UserInRoomMeta } from 'atom.io/realtime';
|
|
7
7
|
import * as atom_io_data from 'atom.io/data';
|
|
8
8
|
import { Loadable } from 'atom.io/data';
|
|
@@ -112,10 +112,19 @@ declare const actionOcclusionAtoms: AtomIO.RegularAtomFamilyToken<{
|
|
|
112
112
|
}, string>;
|
|
113
113
|
declare const userUnacknowledgedQueues: AtomIO.RegularAtomFamilyToken<Pick<TransactionUpdate<any>, "key" | "epoch" | "id" | "updates" | "output">[], string>;
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
type SocketKey = `socket::${string}`;
|
|
116
|
+
type UserKey = `user::${string}`;
|
|
117
|
+
type RoomKey = `room::${string}`;
|
|
118
|
+
type SocketSystemHierarchy = Hierarchy<[
|
|
119
|
+
{
|
|
120
|
+
above: `root`;
|
|
121
|
+
below: [UserKey, SocketKey, RoomKey];
|
|
122
|
+
}
|
|
123
|
+
]>;
|
|
124
|
+
declare const socketAtoms: AtomIO.RegularAtomFamilyToken<Socket | null, `socket::${string}`>;
|
|
116
125
|
declare const socketIndex: AtomIO.MutableAtomToken<SetRTX<string>, SetRTXJson<string>>;
|
|
117
126
|
declare const userIndex: AtomIO.MutableAtomToken<SetRTX<string>, SetRTXJson<string>>;
|
|
118
|
-
declare const usersOfSockets: atom_io_data.JoinToken<"user", "socket", "1:1", null>;
|
|
127
|
+
declare const usersOfSockets: atom_io_data.JoinToken<"user", `user::${string}`, "socket", `socket::${string}`, "1:1", null>;
|
|
119
128
|
|
|
120
129
|
type StateProvider = ReturnType<typeof realtimeStateProvider>;
|
|
121
130
|
declare function realtimeStateProvider({ socket, store, }: ServerConfig): <J extends Json.Serializable>(token: AtomIO.WritableToken<J>) => () => void;
|
|
@@ -136,4 +145,4 @@ type ServerConfig = {
|
|
|
136
145
|
store?: Store;
|
|
137
146
|
};
|
|
138
147
|
|
|
139
|
-
export { type ActionReceiver, ChildSocket, type CreateRoomIO, CustomSocket, type EventBuffer, type Events, type FamilyProvider, type JoinRoomIO, type LeaveRoomIO, type MutableFamilyProvider, type MutableProvider, ParentSocket, type RealtimeContinuitySynchronizer, type RoomArguments, type ServerConfig, type Socket, type StateProvider, type StateReceiver, type StringifiedEvent, SubjectSocket, actionOcclusionAtoms, createRoomTX, destroyRoomTX, joinRoomTX, leaveRoomTX, realtimeActionReceiver, realtimeAtomFamilyProvider, realtimeContinuitySynchronizer, realtimeMutableFamilyProvider, realtimeMutableProvider, realtimeStateProvider, realtimeStateReceiver, redactTransactionUpdateContent, roomArgumentsAtoms, roomSelectors, socketAtoms, socketIndex, userIndex, userUnacknowledgedQueues, usersOfSockets };
|
|
148
|
+
export { type ActionReceiver, ChildSocket, type CreateRoomIO, CustomSocket, type EventBuffer, type Events, type FamilyProvider, type JoinRoomIO, type LeaveRoomIO, type MutableFamilyProvider, type MutableProvider, ParentSocket, type RealtimeContinuitySynchronizer, type RoomArguments, type RoomKey, type ServerConfig, type Socket, type SocketKey, type SocketSystemHierarchy, type StateProvider, type StateReceiver, type StringifiedEvent, SubjectSocket, type UserKey, actionOcclusionAtoms, createRoomTX, destroyRoomTX, joinRoomTX, leaveRoomTX, realtimeActionReceiver, realtimeAtomFamilyProvider, realtimeContinuitySynchronizer, realtimeMutableFamilyProvider, realtimeMutableProvider, realtimeStateProvider, realtimeStateReceiver, redactTransactionUpdateContent, roomArgumentsAtoms, roomSelectors, socketAtoms, socketIndex, userIndex, userUnacknowledgedQueues, usersOfSockets };
|
|
@@ -468,7 +468,9 @@ var userIndex = atom({
|
|
|
468
468
|
var usersOfSockets = join({
|
|
469
469
|
key: `usersOfSockets`,
|
|
470
470
|
between: [`user`, `socket`],
|
|
471
|
-
cardinality: `1:1
|
|
471
|
+
cardinality: `1:1`,
|
|
472
|
+
isAType: (s) => s.startsWith(`user::`),
|
|
473
|
+
isBType: (s) => s.startsWith(`socket::`)
|
|
472
474
|
});
|
|
473
475
|
|
|
474
476
|
// realtime-server/src/realtime-continuity-synchronizer.ts
|
|
@@ -481,7 +483,7 @@ function realtimeContinuitySynchronizer({
|
|
|
481
483
|
const continuityKey = continuity.key;
|
|
482
484
|
const userKeyState = findRelationsInStore(
|
|
483
485
|
usersOfSockets,
|
|
484
|
-
socket.id
|
|
486
|
+
`socket::${socket.id}`,
|
|
485
487
|
store
|
|
486
488
|
).userKeyOfSocket;
|
|
487
489
|
const userKey = getFromStore(store, userKeyState);
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import type { Json, JsonIO } from "atom.io/json"
|
|
16
16
|
import type { ContinuityToken } from "atom.io/realtime"
|
|
17
17
|
|
|
18
|
-
import type { ServerConfig, Socket } from "."
|
|
18
|
+
import type { ServerConfig, Socket, SocketKey } from "."
|
|
19
19
|
import { socketAtoms, usersOfSockets } from "."
|
|
20
20
|
import {
|
|
21
21
|
redactTransactionUpdateContent,
|
|
@@ -35,7 +35,7 @@ export function realtimeContinuitySynchronizer({
|
|
|
35
35
|
const continuityKey = continuity.key
|
|
36
36
|
const userKeyState = findRelationsInStore(
|
|
37
37
|
usersOfSockets,
|
|
38
|
-
socket.id
|
|
38
|
+
`socket::${socket.id}`,
|
|
39
39
|
store,
|
|
40
40
|
).userKeyOfSocket
|
|
41
41
|
const userKey = getFromStore(store, userKeyState)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Hierarchy } from "atom.io"
|
|
1
2
|
import { atom, atomFamily } from "atom.io"
|
|
2
3
|
import { join } from "atom.io/data"
|
|
3
4
|
import type { SetRTXJson } from "atom.io/transceivers/set-rtx"
|
|
@@ -5,7 +6,20 @@ import { SetRTX } from "atom.io/transceivers/set-rtx"
|
|
|
5
6
|
|
|
6
7
|
import type { Socket } from ".."
|
|
7
8
|
|
|
8
|
-
export
|
|
9
|
+
export type SocketKey = `socket::${string}`
|
|
10
|
+
export type UserKey = `user::${string}`
|
|
11
|
+
export type RoomKey = `room::${string}`
|
|
12
|
+
|
|
13
|
+
export type SocketSystemHierarchy = Hierarchy<
|
|
14
|
+
[
|
|
15
|
+
{
|
|
16
|
+
above: `root`
|
|
17
|
+
below: [UserKey, SocketKey, RoomKey]
|
|
18
|
+
},
|
|
19
|
+
]
|
|
20
|
+
>
|
|
21
|
+
|
|
22
|
+
export const socketAtoms = atomFamily<Socket | null, SocketKey>({
|
|
9
23
|
key: `sockets`,
|
|
10
24
|
default: null,
|
|
11
25
|
})
|
|
@@ -28,4 +42,6 @@ export const usersOfSockets = join({
|
|
|
28
42
|
key: `usersOfSockets`,
|
|
29
43
|
between: [`user`, `socket`],
|
|
30
44
|
cardinality: `1:1`,
|
|
45
|
+
isAType: (s): s is UserKey => s.startsWith(`user::`),
|
|
46
|
+
isBType: (s): s is SocketKey => s.startsWith(`socket::`),
|
|
31
47
|
})
|
|
@@ -2,6 +2,7 @@ import '../../dist/chunk-XWL6SNVU.js';
|
|
|
2
2
|
import * as http from 'node:http';
|
|
3
3
|
import { render, prettyDOM } from '@testing-library/react';
|
|
4
4
|
import * as AtomIO from 'atom.io';
|
|
5
|
+
import { realm } from 'atom.io';
|
|
5
6
|
import { editRelationsInStore, findRelationsInStore } from 'atom.io/data';
|
|
6
7
|
import { IMPLICIT, findInStore, setIntoStore, getFromStore, clearStore } from 'atom.io/internal';
|
|
7
8
|
import { toEntries } from 'atom.io/json';
|
|
@@ -32,9 +33,13 @@ function prefixLogger(store, prefix) {
|
|
|
32
33
|
var setupRealtimeTestServer = (options) => {
|
|
33
34
|
++testNumber;
|
|
34
35
|
const silo = new AtomIO.Silo(
|
|
35
|
-
{
|
|
36
|
+
{
|
|
37
|
+
name: `SERVER-${testNumber}`,
|
|
38
|
+
lifespan: options.immortal?.server ? `immortal` : `ephemeral`
|
|
39
|
+
},
|
|
36
40
|
IMPLICIT.STORE
|
|
37
41
|
);
|
|
42
|
+
const socketRealm = realm(silo.store);
|
|
38
43
|
const httpServer = http.createServer((_, res) => res.end(`Hello World!`));
|
|
39
44
|
const address = httpServer.listen(options.port).address();
|
|
40
45
|
const port = typeof address === `string` ? null : address === null ? null : address.port;
|
|
@@ -42,12 +47,14 @@ var setupRealtimeTestServer = (options) => {
|
|
|
42
47
|
const server = new SocketIO.Server(httpServer).use((socket, next) => {
|
|
43
48
|
const { token, username } = socket.handshake.auth;
|
|
44
49
|
if (token === `test` && socket.id) {
|
|
45
|
-
const
|
|
50
|
+
const userClaim = socketRealm.allocate(`root`, `user::${username}`);
|
|
51
|
+
const socketClaim = socketRealm.allocate(`root`, `socket::${socket.id}`);
|
|
52
|
+
const socketState = findInStore(silo.store, RTS.socketAtoms, socketClaim);
|
|
46
53
|
setIntoStore(silo.store, socketState, socket);
|
|
47
54
|
editRelationsInStore(
|
|
48
55
|
RTS.usersOfSockets,
|
|
49
56
|
(relations) => {
|
|
50
|
-
relations.set(
|
|
57
|
+
relations.set(userClaim, socketClaim);
|
|
51
58
|
},
|
|
52
59
|
silo.store
|
|
53
60
|
);
|
|
@@ -64,7 +71,7 @@ var setupRealtimeTestServer = (options) => {
|
|
|
64
71
|
function enableLogging() {
|
|
65
72
|
const userKeyState = findRelationsInStore(
|
|
66
73
|
RTS.usersOfSockets,
|
|
67
|
-
socket.id
|
|
74
|
+
`socket::${socket.id}`,
|
|
68
75
|
silo.store
|
|
69
76
|
).userKeyOfSocket;
|
|
70
77
|
userKey = getFromStore(silo.store, userKeyState);
|
|
@@ -3,6 +3,7 @@ import * as http from "node:http"
|
|
|
3
3
|
import type { RenderResult } from "@testing-library/react"
|
|
4
4
|
import { prettyDOM, render } from "@testing-library/react"
|
|
5
5
|
import * as AtomIO from "atom.io"
|
|
6
|
+
import { realm } from "atom.io"
|
|
6
7
|
import { editRelationsInStore, findRelationsInStore } from "atom.io/data"
|
|
7
8
|
import type { Store } from "atom.io/internal"
|
|
8
9
|
import {
|
|
@@ -44,6 +45,7 @@ function prefixLogger(store: Store, prefix: string) {
|
|
|
44
45
|
|
|
45
46
|
export type TestSetupOptions = {
|
|
46
47
|
port: number
|
|
48
|
+
immortal?: { server?: boolean }
|
|
47
49
|
server: (tools: {
|
|
48
50
|
socket: SocketIO.Socket
|
|
49
51
|
silo: AtomIO.Silo
|
|
@@ -97,9 +99,13 @@ export const setupRealtimeTestServer = (
|
|
|
97
99
|
): RealtimeTestServer => {
|
|
98
100
|
++testNumber
|
|
99
101
|
const silo = new AtomIO.Silo(
|
|
100
|
-
{
|
|
102
|
+
{
|
|
103
|
+
name: `SERVER-${testNumber}`,
|
|
104
|
+
lifespan: options.immortal?.server ? `immortal` : `ephemeral`,
|
|
105
|
+
},
|
|
101
106
|
IMPLICIT.STORE,
|
|
102
107
|
)
|
|
108
|
+
const socketRealm = realm<RTS.SocketSystemHierarchy>(silo.store)
|
|
103
109
|
|
|
104
110
|
const httpServer = http.createServer((_, res) => res.end(`Hello World!`))
|
|
105
111
|
const address = httpServer.listen(options.port).address()
|
|
@@ -110,12 +116,14 @@ export const setupRealtimeTestServer = (
|
|
|
110
116
|
const server = new SocketIO.Server(httpServer).use((socket, next) => {
|
|
111
117
|
const { token, username } = socket.handshake.auth
|
|
112
118
|
if (token === `test` && socket.id) {
|
|
113
|
-
const
|
|
119
|
+
const userClaim = socketRealm.allocate(`root`, `user::${username}`)
|
|
120
|
+
const socketClaim = socketRealm.allocate(`root`, `socket::${socket.id}`)
|
|
121
|
+
const socketState = findInStore(silo.store, RTS.socketAtoms, socketClaim)
|
|
114
122
|
setIntoStore(silo.store, socketState, socket)
|
|
115
123
|
editRelationsInStore(
|
|
116
124
|
RTS.usersOfSockets,
|
|
117
125
|
(relations) => {
|
|
118
|
-
relations.set(
|
|
126
|
+
relations.set(userClaim, socketClaim)
|
|
119
127
|
},
|
|
120
128
|
silo.store,
|
|
121
129
|
)
|
|
@@ -133,7 +141,7 @@ export const setupRealtimeTestServer = (
|
|
|
133
141
|
function enableLogging() {
|
|
134
142
|
const userKeyState = findRelationsInStore(
|
|
135
143
|
RTS.usersOfSockets,
|
|
136
|
-
socket.id
|
|
144
|
+
`socket::${socket.id}`,
|
|
137
145
|
silo.store,
|
|
138
146
|
).userKeyOfSocket
|
|
139
147
|
userKey = getFromStore(silo.store, userKeyState)
|
package/src/allocate.ts
CHANGED
|
@@ -29,7 +29,6 @@ export function allocateIntoStore<
|
|
|
29
29
|
A extends Above<V, H>,
|
|
30
30
|
>(store: Store, provenance: A, key: V): Claim<H, V, A> {
|
|
31
31
|
const stringKey = stringifyJson(key)
|
|
32
|
-
|
|
33
32
|
try {
|
|
34
33
|
const above: Molecule<any>[] = []
|
|
35
34
|
|
|
@@ -38,7 +37,7 @@ export function allocateIntoStore<
|
|
|
38
37
|
// biome-ignore lint/style/noNonNullAssertion: let's assume we made the root molecule to get here
|
|
39
38
|
above.push(store.molecules.get(`"root"`)!)
|
|
40
39
|
allocationAttachmentStyle = `all`
|
|
41
|
-
} else if (provenance
|
|
40
|
+
} else if (typeof provenance === `string` && provenance.startsWith(T$)) {
|
|
42
41
|
allocationAttachmentStyle = `any`
|
|
43
42
|
const provenanceKey = stringifyJson(provenance as Canonical)
|
|
44
43
|
const provenanceMolecule = store.molecules.get(provenanceKey)
|
|
@@ -49,7 +48,7 @@ export function allocateIntoStore<
|
|
|
49
48
|
}
|
|
50
49
|
above.push(provenanceMolecule)
|
|
51
50
|
} else {
|
|
52
|
-
const allocationIsCompound = key
|
|
51
|
+
const allocationIsCompound = key.startsWith(`T$--`)
|
|
53
52
|
if (allocationIsCompound) {
|
|
54
53
|
allocationAttachmentStyle = `all`
|
|
55
54
|
for (const claim of provenance as SingularTypedKey[]) {
|
|
@@ -150,11 +149,11 @@ export function deallocateFromStore<
|
|
|
150
149
|
}
|
|
151
150
|
for (const child of molecule.below.values()) {
|
|
152
151
|
if (child.dependsOn === `all`) {
|
|
153
|
-
deallocateFromStore(store, child.key)
|
|
152
|
+
deallocateFromStore<any, any, any>(store, child.key)
|
|
154
153
|
} else {
|
|
155
154
|
child.above.delete(molecule.stringKey)
|
|
156
155
|
if (child.above.size === 0) {
|
|
157
|
-
deallocateFromStore(store, child.key)
|
|
156
|
+
deallocateFromStore<any, any, any>(store, child.key)
|
|
158
157
|
}
|
|
159
158
|
}
|
|
160
159
|
}
|
|
@@ -203,13 +202,13 @@ export function realm<H extends Hierarchy>(store: Store) {
|
|
|
203
202
|
|
|
204
203
|
export const T$ = `T$`
|
|
205
204
|
export type T$ = typeof T$
|
|
206
|
-
export type TypeTag<T extends string> =
|
|
207
|
-
export type SingularTypedKey<T extends string = string> =
|
|
205
|
+
export type TypeTag<T extends string> = `${T$}--${T}`
|
|
206
|
+
export type SingularTypedKey<T extends string = string> = `${T}::${string}`
|
|
208
207
|
export type CompoundTypedKey<
|
|
209
208
|
A extends string = string,
|
|
210
209
|
B extends string = string,
|
|
211
210
|
C extends string = string,
|
|
212
|
-
> =
|
|
211
|
+
> = `${TypeTag<A>}==${SingularTypedKey<B>}++${SingularTypedKey<C>}`
|
|
213
212
|
export type TypedKey<
|
|
214
213
|
A extends string = string,
|
|
215
214
|
B extends string = string,
|
package/src/index.ts
CHANGED
package/src/molecule.ts
CHANGED
|
@@ -38,12 +38,14 @@ export type CtorToolkit<K extends Canonical> = Flat<
|
|
|
38
38
|
bond<T>(family: ReadonlySelectorFamilyToken<T, K>): ReadonlySelectorToken<T>
|
|
39
39
|
bond<T>(family: WritableFamilyToken<T, K>): WritableToken<T>
|
|
40
40
|
bond<T>(family: ReadableFamilyToken<T, K>): ReadableToken<T>
|
|
41
|
-
bond<J extends JoinToken<any, any, any, any>>(
|
|
41
|
+
bond<J extends JoinToken<any, any, any, any, any, any>>(
|
|
42
42
|
joinToken: J,
|
|
43
43
|
role: {
|
|
44
|
-
as: J extends JoinToken<infer A, infer B, any, any>
|
|
44
|
+
as: J extends JoinToken<infer A, string, infer B, string, any, any>
|
|
45
|
+
? A | B
|
|
46
|
+
: never
|
|
45
47
|
},
|
|
46
|
-
): J extends JoinToken<any, any, any, infer Content>
|
|
48
|
+
): J extends JoinToken<any, any, any, any, any, infer Content>
|
|
47
49
|
? Content extends null
|
|
48
50
|
? { relatedKeys: ReadonlySelectorToken<string[]> }
|
|
49
51
|
: {
|
package/dist/chunk-ZKG6ZA4I.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { createMoleculeFamily, IMPLICIT, makeMoleculeInStore, Molecule } from 'atom.io/internal';
|
|
2
|
-
import { stringifyJson } from 'atom.io/json';
|
|
3
|
-
|
|
4
|
-
// src/molecule.ts
|
|
5
|
-
function moleculeFamily(options) {
|
|
6
|
-
return createMoleculeFamily(IMPLICIT.STORE, options);
|
|
7
|
-
}
|
|
8
|
-
function makeMolecule(context, family, key, ...params) {
|
|
9
|
-
return makeMoleculeInStore(IMPLICIT.STORE, context, family, key, ...params);
|
|
10
|
-
}
|
|
11
|
-
function makeRootMoleculeInStore(key, store = IMPLICIT.STORE) {
|
|
12
|
-
const molecule = new Molecule(void 0, key);
|
|
13
|
-
store.molecules.set(stringifyJson(key), molecule);
|
|
14
|
-
return {
|
|
15
|
-
key,
|
|
16
|
-
type: `molecule`
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export { makeMolecule, makeRootMoleculeInStore, moleculeFamily };
|