atom.io 0.27.4 → 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 +65 -81
- package/data/src/dict.ts +9 -12
- package/data/src/join.ts +30 -33
- package/data/src/struct-family.ts +17 -23
- package/data/src/struct.ts +9 -12
- package/dist/{chunk-JRENM6KL.js → chunk-BX3MTH2Z.js} +482 -385
- package/dist/chunk-D52JNVER.js +721 -0
- package/dist/chunk-EUVKUTW3.js +89 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +35 -53
- package/ephemeral/dist/index.js +1 -1
- package/ephemeral/src/find-state.ts +1 -1
- package/immortal/dist/index.js +2 -2
- package/immortal/src/seek-state.ts +2 -2
- package/internal/dist/index.d.ts +141 -87
- package/internal/dist/index.js +1 -1
- package/internal/src/atom/create-regular-atom.ts +3 -3
- package/internal/src/atom/create-standalone-atom.ts +7 -5
- package/internal/src/atom/dispose-atom.ts +2 -9
- package/internal/src/families/create-atom-family.ts +5 -5
- package/internal/src/families/create-readonly-selector-family.ts +20 -9
- package/internal/src/families/create-regular-atom-family.ts +15 -6
- package/internal/src/families/create-selector-family.ts +5 -5
- package/internal/src/families/create-writable-selector-family.ts +20 -10
- package/internal/src/families/dispose-from-store.ts +43 -29
- package/internal/src/families/find-in-store.ts +28 -18
- package/internal/src/families/init-family-member.ts +9 -9
- package/internal/src/families/seek-in-store.ts +10 -10
- package/internal/src/get-state/get-from-store.ts +70 -47
- package/internal/src/ingest-updates/ingest-atom-update.ts +1 -1
- package/internal/src/ingest-updates/ingest-creation-disposal.ts +15 -6
- package/internal/src/molecule/create-molecule-family.ts +1 -1
- package/internal/src/molecule/dispose-molecule.ts +7 -18
- package/internal/src/molecule/grow-molecule-in-store.ts +1 -1
- package/internal/src/molecule/make-molecule-in-store.ts +5 -5
- package/internal/src/mutable/create-mutable-atom-family.ts +15 -6
- package/internal/src/mutable/create-mutable-atom.ts +3 -3
- package/internal/src/mutable/get-json-token.ts +2 -2
- package/internal/src/mutable/tracker-family.ts +3 -3
- package/internal/src/mutable/tracker.ts +14 -18
- package/internal/src/pretty-print.ts +1 -16
- package/internal/src/selector/create-readonly-selector.ts +2 -2
- package/internal/src/selector/create-standalone-selector.ts +5 -5
- package/internal/src/selector/create-writable-selector.ts +2 -2
- package/internal/src/selector/dispose-selector.ts +2 -9
- package/internal/src/selector/register-selector.ts +9 -9
- package/internal/src/set-state/set-into-store.ts +23 -33
- package/internal/src/store/circular-buffer.ts +34 -0
- package/internal/src/store/counterfeit.ts +109 -0
- package/internal/src/store/deposit.ts +67 -13
- package/internal/src/store/index.ts +1 -0
- package/internal/src/store/store.ts +4 -1
- package/internal/src/store/withdraw.ts +15 -10
- package/internal/src/subscribe/index.ts +2 -0
- package/internal/src/subscribe/subscribe-in-store.ts +62 -0
- package/internal/src/timeline/time-travel.ts +1 -1
- package/internal/src/transaction/build-transaction.ts +7 -6
- package/introspection/dist/index.d.ts +84 -4
- package/introspection/dist/index.js +1 -413
- package/introspection/src/attach-atom-index.ts +5 -8
- package/introspection/src/attach-introspection-states.ts +7 -4
- package/introspection/src/attach-selector-index.ts +6 -8
- package/introspection/src/attach-timeline-family.ts +25 -28
- package/introspection/src/attach-timeline-index.ts +5 -8
- package/introspection/src/attach-transaction-index.ts +5 -8
- package/introspection/src/attach-transaction-logs.ts +21 -27
- 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 -80
- package/json/src/entries.ts +6 -0
- package/json/src/index.ts +47 -6
- package/json/src/select-json-family.ts +4 -4
- package/json/src/select-json.ts +6 -9
- package/package.json +17 -8
- package/react/dist/index.js +7 -7
- package/react/src/parse-state-overloads.ts +2 -2
- package/react/src/use-i.ts +1 -1
- package/react/src/use-json.ts +2 -2
- package/react/src/use-o.ts +2 -2
- 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 +59 -65
- package/realtime-client/src/pull-atom-family-member.ts +1 -1
- package/realtime-client/src/pull-atom.ts +1 -1
- package/realtime-client/src/pull-mutable-atom-family-member.ts +3 -3
- package/realtime-client/src/pull-mutable-atom.ts +3 -3
- package/realtime-client/src/realtime-client-stores/client-main-store.ts +6 -6
- package/realtime-client/src/sync-continuity.ts +55 -53
- package/realtime-react/dist/index.js +3 -3
- package/realtime-react/src/use-pull-atom-family-member.ts +1 -1
- package/realtime-react/src/use-pull-mutable-family-member.ts +1 -1
- package/realtime-react/src/use-pull-selector-family-member.ts +1 -1
- package/realtime-server/dist/index.js +72 -36
- package/realtime-server/src/realtime-continuity-synchronizer.ts +57 -93
- package/realtime-server/src/realtime-family-provider.ts +3 -3
- package/realtime-server/src/realtime-mutable-family-provider.ts +5 -5
- package/realtime-server/src/realtime-mutable-provider.ts +2 -2
- package/realtime-server/src/realtime-state-provider.ts +1 -1
- package/realtime-server/src/realtime-state-receiver.ts +1 -1
- package/realtime-testing/dist/index.d.ts +2 -0
- package/realtime-testing/dist/index.js +57 -15
- package/realtime-testing/src/setup-realtime-test.tsx +66 -16
- package/src/atom.ts +2 -2
- package/src/dispose-state.ts +2 -2
- package/src/get-state.ts +9 -13
- package/src/molecule.ts +1 -1
- package/src/selector.ts +2 -2
- package/src/set-state.ts +10 -7
- package/src/silo.ts +29 -55
- package/src/subscribe.ts +3 -23
- package/src/timeline.ts +2 -2
- 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
- package/internal/src/families/throw-in-case-of-conflicting-family.ts +0 -18
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { recordToEntries } from '../../dist/chunk-IW6WYRS7.js';
|
|
2
1
|
import '../../dist/chunk-XWL6SNVU.js';
|
|
3
2
|
import * as http from 'http';
|
|
4
3
|
import { render, prettyDOM } from '@testing-library/react';
|
|
5
4
|
import * as AtomIO from 'atom.io';
|
|
6
|
-
import { editRelationsInStore } from 'atom.io/data';
|
|
5
|
+
import { editRelationsInStore, findRelationsInStore } from 'atom.io/data';
|
|
7
6
|
import { IMPLICIT, findInStore, setIntoStore, getFromStore, clearStore } from 'atom.io/internal';
|
|
7
|
+
import { toEntries } from 'atom.io/json';
|
|
8
8
|
import * as AR from 'atom.io/react';
|
|
9
9
|
import * as RT from 'atom.io/realtime';
|
|
10
|
-
import
|
|
10
|
+
import * as RTC from 'atom.io/realtime-client';
|
|
11
11
|
import * as RTR from 'atom.io/realtime-react';
|
|
12
12
|
import * as RTS from 'atom.io/realtime-server';
|
|
13
13
|
import * as Happy from 'happy-dom';
|
|
@@ -16,6 +16,19 @@ import { io } from 'socket.io-client';
|
|
|
16
16
|
import { jsx } from 'react/jsx-runtime';
|
|
17
17
|
|
|
18
18
|
var testNumber = 0;
|
|
19
|
+
function prefixLogger(store, prefix) {
|
|
20
|
+
store.loggers[0] = new AtomIO.AtomIOLogger(`info`, void 0, {
|
|
21
|
+
info: (...args) => {
|
|
22
|
+
console.info(prefix, ...args);
|
|
23
|
+
},
|
|
24
|
+
warn: (...args) => {
|
|
25
|
+
console.warn(prefix, ...args);
|
|
26
|
+
},
|
|
27
|
+
error: (...args) => {
|
|
28
|
+
console.error(prefix, ...args);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
19
32
|
var setupRealtimeTestServer = (options) => {
|
|
20
33
|
++testNumber;
|
|
21
34
|
const silo = new AtomIO.Silo(
|
|
@@ -29,8 +42,8 @@ var setupRealtimeTestServer = (options) => {
|
|
|
29
42
|
const server = new SocketIO.Server(httpServer).use((socket, next) => {
|
|
30
43
|
const { token, username } = socket.handshake.auth;
|
|
31
44
|
if (token === `test` && socket.id) {
|
|
32
|
-
const socketState = findInStore(RTS.socketAtoms, socket.id
|
|
33
|
-
setIntoStore(socketState, socket
|
|
45
|
+
const socketState = findInStore(silo.store, RTS.socketAtoms, socket.id);
|
|
46
|
+
setIntoStore(silo.store, socketState, socket);
|
|
34
47
|
editRelationsInStore(
|
|
35
48
|
RTS.usersOfSockets,
|
|
36
49
|
(relations) => {
|
|
@@ -38,8 +51,8 @@ var setupRealtimeTestServer = (options) => {
|
|
|
38
51
|
},
|
|
39
52
|
silo.store
|
|
40
53
|
);
|
|
41
|
-
setIntoStore(RTS.userIndex, (index) => index.add(username)
|
|
42
|
-
setIntoStore(RTS.socketIndex, (index) => index.add(socket.id)
|
|
54
|
+
setIntoStore(silo.store, RTS.userIndex, (index) => index.add(username));
|
|
55
|
+
setIntoStore(silo.store, RTS.socketIndex, (index) => index.add(socket.id));
|
|
43
56
|
console.log(`${username} connected on ${socket.id}`);
|
|
44
57
|
next();
|
|
45
58
|
} else {
|
|
@@ -47,14 +60,33 @@ var setupRealtimeTestServer = (options) => {
|
|
|
47
60
|
}
|
|
48
61
|
});
|
|
49
62
|
server.on(`connection`, (socket) => {
|
|
50
|
-
|
|
63
|
+
let userKey = null;
|
|
64
|
+
function enableLogging() {
|
|
65
|
+
const userKeyState = findRelationsInStore(
|
|
66
|
+
RTS.usersOfSockets,
|
|
67
|
+
socket.id,
|
|
68
|
+
silo.store
|
|
69
|
+
).userKeyOfSocket;
|
|
70
|
+
userKey = getFromStore(silo.store, userKeyState);
|
|
71
|
+
prefixLogger(silo.store, `server`);
|
|
72
|
+
socket.onAny((event, ...args) => {
|
|
73
|
+
console.log(`\u{1F6F0} `, userKey, event, ...args);
|
|
74
|
+
});
|
|
75
|
+
socket.onAnyOutgoing((event, ...args) => {
|
|
76
|
+
console.log(`\u{1F6F0} >>`, userKey, event, ...args);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
options.server({ socket, enableLogging, silo });
|
|
80
|
+
socket.on(`disconnect`, () => {
|
|
81
|
+
console.log(`${userKey} disconnected`);
|
|
82
|
+
});
|
|
51
83
|
});
|
|
52
84
|
const dispose = () => {
|
|
53
85
|
server.close();
|
|
54
|
-
const roomKeys = getFromStore(
|
|
86
|
+
const roomKeys = getFromStore(silo.store, RT.roomIndex);
|
|
55
87
|
for (const roomKey of roomKeys) {
|
|
56
|
-
const roomState = findInStore(RTS.roomSelectors, roomKey
|
|
57
|
-
const room = getFromStore(
|
|
88
|
+
const roomState = findInStore(silo.store, RTS.roomSelectors, roomKey);
|
|
89
|
+
const room = getFromStore(silo.store, roomState);
|
|
58
90
|
if (room && !(room instanceof Promise)) {
|
|
59
91
|
room.process.kill();
|
|
60
92
|
}
|
|
@@ -81,7 +113,7 @@ var setupRealtimeTestClient = (options, name, port) => {
|
|
|
81
113
|
silo.store.valueMap.set(key, [...value]);
|
|
82
114
|
}
|
|
83
115
|
}
|
|
84
|
-
silo.setState(myUsernameState, `${name}-${testNumber}`);
|
|
116
|
+
silo.setState(RTC.myUsernameState, `${name}-${testNumber}`);
|
|
85
117
|
const { document } = new Happy.Window();
|
|
86
118
|
document.body.innerHTML = `<div id="app"></div>`;
|
|
87
119
|
const renderResult = render(
|
|
@@ -93,6 +125,15 @@ var setupRealtimeTestClient = (options, name, port) => {
|
|
|
93
125
|
const prettyPrint = () => {
|
|
94
126
|
console.log(prettyDOM(renderResult.container));
|
|
95
127
|
};
|
|
128
|
+
const enableLogging = () => {
|
|
129
|
+
prefixLogger(silo.store, name);
|
|
130
|
+
socket.onAny((event, ...args) => {
|
|
131
|
+
console.log(`\u{1F4E1} `, name, event, ...args);
|
|
132
|
+
});
|
|
133
|
+
socket.onAnyOutgoing((event, ...args) => {
|
|
134
|
+
console.log(`\u{1F4E1} >>`, name, event, ...args);
|
|
135
|
+
});
|
|
136
|
+
};
|
|
96
137
|
const dispose = () => {
|
|
97
138
|
renderResult.unmount();
|
|
98
139
|
socket.disconnect();
|
|
@@ -104,7 +145,8 @@ var setupRealtimeTestClient = (options, name, port) => {
|
|
|
104
145
|
silo,
|
|
105
146
|
socket,
|
|
106
147
|
renderResult,
|
|
107
|
-
prettyPrint
|
|
148
|
+
prettyPrint,
|
|
149
|
+
enableLogging
|
|
108
150
|
};
|
|
109
151
|
};
|
|
110
152
|
return Object.assign(testClient, { init });
|
|
@@ -123,7 +165,7 @@ var singleClient = (options) => {
|
|
|
123
165
|
};
|
|
124
166
|
var multiClient = (options) => {
|
|
125
167
|
const server = setupRealtimeTestServer(options);
|
|
126
|
-
const clients =
|
|
168
|
+
const clients = toEntries(options.clients).reduce(
|
|
127
169
|
(clientRecord, [name, client]) => {
|
|
128
170
|
clientRecord[name] = setupRealtimeTestClient(
|
|
129
171
|
{ ...options, client },
|
|
@@ -139,7 +181,7 @@ var multiClient = (options) => {
|
|
|
139
181
|
server,
|
|
140
182
|
teardown: () => {
|
|
141
183
|
server.dispose();
|
|
142
|
-
for (const [, client] of
|
|
184
|
+
for (const [, client] of toEntries(clients)) {
|
|
143
185
|
client.dispose();
|
|
144
186
|
}
|
|
145
187
|
}
|
|
@@ -3,7 +3,8 @@ 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 { editRelationsInStore } from "atom.io/data"
|
|
6
|
+
import { editRelationsInStore, findRelationsInStore } from "atom.io/data"
|
|
7
|
+
import type { Store } from "atom.io/internal"
|
|
7
8
|
import {
|
|
8
9
|
clearStore,
|
|
9
10
|
findInStore,
|
|
@@ -11,9 +12,10 @@ import {
|
|
|
11
12
|
IMPLICIT,
|
|
12
13
|
setIntoStore,
|
|
13
14
|
} from "atom.io/internal"
|
|
15
|
+
import { toEntries } from "atom.io/json"
|
|
14
16
|
import * as AR from "atom.io/react"
|
|
15
17
|
import * as RT from "atom.io/realtime"
|
|
16
|
-
import
|
|
18
|
+
import * as RTC from "atom.io/realtime-client"
|
|
17
19
|
import * as RTR from "atom.io/realtime-react"
|
|
18
20
|
import * as RTS from "atom.io/realtime-server"
|
|
19
21
|
import * as Happy from "happy-dom"
|
|
@@ -22,13 +24,29 @@ import * as SocketIO from "socket.io"
|
|
|
22
24
|
import type { Socket as ClientSocket } from "socket.io-client"
|
|
23
25
|
import { io } from "socket.io-client"
|
|
24
26
|
|
|
25
|
-
import { recordToEntries } from "~/packages/anvl/src/object"
|
|
26
|
-
|
|
27
27
|
let testNumber = 0
|
|
28
28
|
|
|
29
|
+
function prefixLogger(store: Store, prefix: string) {
|
|
30
|
+
store.loggers[0] = new AtomIO.AtomIOLogger(`info`, undefined, {
|
|
31
|
+
info: (...args) => {
|
|
32
|
+
console.info(prefix, ...args)
|
|
33
|
+
},
|
|
34
|
+
warn: (...args) => {
|
|
35
|
+
console.warn(prefix, ...args)
|
|
36
|
+
},
|
|
37
|
+
error: (...args) => {
|
|
38
|
+
console.error(prefix, ...args)
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
29
43
|
export type TestSetupOptions = {
|
|
30
44
|
port: number
|
|
31
|
-
server: (tools: {
|
|
45
|
+
server: (tools: {
|
|
46
|
+
socket: SocketIO.Socket
|
|
47
|
+
silo: AtomIO.Silo
|
|
48
|
+
enableLogging: () => void
|
|
49
|
+
}) => void
|
|
32
50
|
}
|
|
33
51
|
export type TestSetupOptions__SingleClient = TestSetupOptions & {
|
|
34
52
|
client: React.FC
|
|
@@ -47,6 +65,7 @@ export type RealtimeTestTools = {
|
|
|
47
65
|
export type RealtimeTestClient = RealtimeTestTools & {
|
|
48
66
|
renderResult: RenderResult
|
|
49
67
|
prettyPrint: () => void
|
|
68
|
+
enableLogging: () => void
|
|
50
69
|
socket: ClientSocket
|
|
51
70
|
}
|
|
52
71
|
export type RealtimeTestClientBuilder = {
|
|
@@ -57,6 +76,7 @@ export type RealtimeTestClientBuilder = {
|
|
|
57
76
|
export type RealtimeTestServer = RealtimeTestTools & {
|
|
58
77
|
dispose: () => void
|
|
59
78
|
port: number
|
|
79
|
+
// enableLogging: () => void
|
|
60
80
|
}
|
|
61
81
|
|
|
62
82
|
export type RealtimeTestAPI = {
|
|
@@ -89,8 +109,8 @@ export const setupRealtimeTestServer = (
|
|
|
89
109
|
const server = new SocketIO.Server(httpServer).use((socket, next) => {
|
|
90
110
|
const { token, username } = socket.handshake.auth
|
|
91
111
|
if (token === `test` && socket.id) {
|
|
92
|
-
const socketState = findInStore(RTS.socketAtoms, socket.id
|
|
93
|
-
setIntoStore(socketState, socket
|
|
112
|
+
const socketState = findInStore(silo.store, RTS.socketAtoms, socket.id)
|
|
113
|
+
setIntoStore(silo.store, socketState, socket)
|
|
94
114
|
editRelationsInStore(
|
|
95
115
|
RTS.usersOfSockets,
|
|
96
116
|
(relations) => {
|
|
@@ -98,8 +118,8 @@ export const setupRealtimeTestServer = (
|
|
|
98
118
|
},
|
|
99
119
|
silo.store,
|
|
100
120
|
)
|
|
101
|
-
setIntoStore(RTS.userIndex, (index) => index.add(username)
|
|
102
|
-
setIntoStore(RTS.socketIndex, (index) => index.add(socket.id)
|
|
121
|
+
setIntoStore(silo.store, RTS.userIndex, (index) => index.add(username))
|
|
122
|
+
setIntoStore(silo.store, RTS.socketIndex, (index) => index.add(socket.id))
|
|
103
123
|
console.log(`${username} connected on ${socket.id}`)
|
|
104
124
|
next()
|
|
105
125
|
} else {
|
|
@@ -108,15 +128,34 @@ export const setupRealtimeTestServer = (
|
|
|
108
128
|
})
|
|
109
129
|
|
|
110
130
|
server.on(`connection`, (socket: SocketIO.Socket) => {
|
|
111
|
-
|
|
131
|
+
let userKey: string | null = null
|
|
132
|
+
function enableLogging() {
|
|
133
|
+
const userKeyState = findRelationsInStore(
|
|
134
|
+
RTS.usersOfSockets,
|
|
135
|
+
socket.id,
|
|
136
|
+
silo.store,
|
|
137
|
+
).userKeyOfSocket
|
|
138
|
+
userKey = getFromStore(silo.store, userKeyState)
|
|
139
|
+
prefixLogger(silo.store, `server`)
|
|
140
|
+
socket.onAny((event, ...args) => {
|
|
141
|
+
console.log(`🛰 `, userKey, event, ...args)
|
|
142
|
+
})
|
|
143
|
+
socket.onAnyOutgoing((event, ...args) => {
|
|
144
|
+
console.log(`🛰 >>`, userKey, event, ...args)
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
options.server({ socket, enableLogging, silo })
|
|
148
|
+
socket.on(`disconnect`, () => {
|
|
149
|
+
console.log(`${userKey} disconnected`)
|
|
150
|
+
})
|
|
112
151
|
})
|
|
113
152
|
|
|
114
153
|
const dispose = () => {
|
|
115
154
|
server.close()
|
|
116
|
-
const roomKeys = getFromStore(
|
|
155
|
+
const roomKeys = getFromStore(silo.store, RT.roomIndex)
|
|
117
156
|
for (const roomKey of roomKeys) {
|
|
118
|
-
const roomState = findInStore(RTS.roomSelectors, roomKey
|
|
119
|
-
const room = getFromStore(
|
|
157
|
+
const roomState = findInStore(silo.store, RTS.roomSelectors, roomKey)
|
|
158
|
+
const room = getFromStore(silo.store, roomState)
|
|
120
159
|
if (room && !(room instanceof Promise)) {
|
|
121
160
|
room.process.kill()
|
|
122
161
|
}
|
|
@@ -147,7 +186,7 @@ export const setupRealtimeTestClient = (
|
|
|
147
186
|
silo.store.valueMap.set(key, [...value])
|
|
148
187
|
}
|
|
149
188
|
}
|
|
150
|
-
silo.setState(myUsernameState, `${name}-${testNumber}`)
|
|
189
|
+
silo.setState(RTC.myUsernameState, `${name}-${testNumber}`)
|
|
151
190
|
|
|
152
191
|
const { document } = new Happy.Window()
|
|
153
192
|
document.body.innerHTML = `<div id="app"></div>`
|
|
@@ -166,6 +205,16 @@ export const setupRealtimeTestClient = (
|
|
|
166
205
|
console.log(prettyDOM(renderResult.container))
|
|
167
206
|
}
|
|
168
207
|
|
|
208
|
+
const enableLogging = () => {
|
|
209
|
+
prefixLogger(silo.store, name)
|
|
210
|
+
socket.onAny((event, ...args) => {
|
|
211
|
+
console.log(`📡 `, name, event, ...args)
|
|
212
|
+
})
|
|
213
|
+
socket.onAnyOutgoing((event, ...args) => {
|
|
214
|
+
console.log(`📡 >>`, name, event, ...args)
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
|
|
169
218
|
const dispose = () => {
|
|
170
219
|
renderResult.unmount()
|
|
171
220
|
socket.disconnect()
|
|
@@ -179,6 +228,7 @@ export const setupRealtimeTestClient = (
|
|
|
179
228
|
socket,
|
|
180
229
|
renderResult,
|
|
181
230
|
prettyPrint,
|
|
231
|
+
enableLogging,
|
|
182
232
|
}
|
|
183
233
|
}
|
|
184
234
|
return Object.assign(testClient, { init })
|
|
@@ -204,7 +254,7 @@ export const multiClient = <ClientNames extends string>(
|
|
|
204
254
|
options: TestSetupOptions__MultiClient<ClientNames>,
|
|
205
255
|
): RealtimeTestAPI__MultiClient<ClientNames> => {
|
|
206
256
|
const server = setupRealtimeTestServer(options)
|
|
207
|
-
const clients =
|
|
257
|
+
const clients = toEntries(options.clients).reduce(
|
|
208
258
|
(clientRecord, [name, client]) => {
|
|
209
259
|
clientRecord[name] = setupRealtimeTestClient(
|
|
210
260
|
{ ...options, client },
|
|
@@ -221,7 +271,7 @@ export const multiClient = <ClientNames extends string>(
|
|
|
221
271
|
server,
|
|
222
272
|
teardown: () => {
|
|
223
273
|
server.dispose()
|
|
224
|
-
for (const [, client] of
|
|
274
|
+
for (const [, client] of toEntries(clients)) {
|
|
225
275
|
client.dispose()
|
|
226
276
|
}
|
|
227
277
|
},
|
package/src/atom.ts
CHANGED
|
@@ -53,7 +53,7 @@ export function atom<T>(options: RegularAtomOptions<T>): RegularAtomToken<T>
|
|
|
53
53
|
export function atom(
|
|
54
54
|
options: MutableAtomOptions<any, any> | RegularAtomOptions<any>,
|
|
55
55
|
): AtomToken<any> {
|
|
56
|
-
return createStandaloneAtom(
|
|
56
|
+
return createStandaloneAtom(IMPLICIT.STORE, options)
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export type RegularAtomFamilyOptions<T, K extends Canonical> = {
|
|
@@ -112,5 +112,5 @@ export function atomFamily<T, K extends Canonical>(
|
|
|
112
112
|
| MutableAtomFamilyOptions<any, any, any>
|
|
113
113
|
| RegularAtomFamilyOptions<T, K>,
|
|
114
114
|
): MutableAtomFamilyToken<any, any, any> | RegularAtomFamilyToken<T, K> {
|
|
115
|
-
return createAtomFamily(
|
|
115
|
+
return createAtomFamily(IMPLICIT.STORE, options)
|
|
116
116
|
}
|
package/src/dispose-state.ts
CHANGED
|
@@ -32,8 +32,8 @@ export function disposeState(
|
|
|
32
32
|
key?: Json.Serializable,
|
|
33
33
|
): void {
|
|
34
34
|
if (key) {
|
|
35
|
-
Internal.disposeFromStore(token as any, key
|
|
35
|
+
Internal.disposeFromStore(Internal.IMPLICIT.STORE, token as any, key)
|
|
36
36
|
} else {
|
|
37
|
-
Internal.disposeFromStore(token as any
|
|
37
|
+
Internal.disposeFromStore(Internal.IMPLICIT.STORE, token as any)
|
|
38
38
|
}
|
|
39
39
|
}
|
package/src/get-state.ts
CHANGED
|
@@ -26,19 +26,15 @@ export function getState<M extends MoleculeConstructor>(
|
|
|
26
26
|
): InstanceType<M>
|
|
27
27
|
|
|
28
28
|
export function getState(
|
|
29
|
-
|
|
30
|
-
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
...params:
|
|
30
|
+
| [
|
|
31
|
+
token: MoleculeFamilyToken<any> | ReadableFamilyToken<any, any>,
|
|
32
|
+
key: Canonical,
|
|
33
|
+
]
|
|
34
|
+
| [token: MoleculeToken<any> | ReadableToken<any>]
|
|
35
35
|
): any {
|
|
36
|
-
if (
|
|
37
|
-
return Internal.getFromStore(
|
|
38
|
-
token as any,
|
|
39
|
-
key as any,
|
|
40
|
-
Internal.IMPLICIT.STORE,
|
|
41
|
-
)
|
|
36
|
+
if (params.length === 2) {
|
|
37
|
+
return Internal.getFromStore(Internal.IMPLICIT.STORE, ...params)
|
|
42
38
|
}
|
|
43
|
-
return Internal.getFromStore(
|
|
39
|
+
return Internal.getFromStore(Internal.IMPLICIT.STORE, ...params)
|
|
44
40
|
}
|
package/src/molecule.ts
CHANGED
|
@@ -101,7 +101,7 @@ export type MoleculeToken<M extends MoleculeConstructor> = {
|
|
|
101
101
|
export function moleculeFamily<M extends MoleculeConstructor>(
|
|
102
102
|
options: MoleculeFamilyOptions<M>,
|
|
103
103
|
): MoleculeFamilyToken<M> {
|
|
104
|
-
return createMoleculeFamily(
|
|
104
|
+
return createMoleculeFamily(IMPLICIT.STORE, options)
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
export function makeMolecule<M extends MoleculeConstructor>(
|
package/src/selector.ts
CHANGED
|
@@ -27,7 +27,7 @@ export function selector<T>(
|
|
|
27
27
|
export function selector<T>(
|
|
28
28
|
options: ReadonlySelectorOptions<T> | WritableSelectorOptions<T>,
|
|
29
29
|
): ReadonlySelectorToken<T> | WritableSelectorToken<T> {
|
|
30
|
-
return createStandaloneSelector(
|
|
30
|
+
return createStandaloneSelector(IMPLICIT.STORE, options)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export type WritableSelectorFamilyOptions<T, K extends Canonical> = {
|
|
@@ -69,5 +69,5 @@ export function selectorFamily<T, K extends Canonical>(
|
|
|
69
69
|
| ReadonlySelectorFamilyOptions<T, K>
|
|
70
70
|
| WritableSelectorFamilyOptions<T, K>,
|
|
71
71
|
): ReadonlySelectorFamilyToken<T, K> | WritableSelectorFamilyToken<T, K> {
|
|
72
|
-
return createSelectorFamily(
|
|
72
|
+
return createSelectorFamily(IMPLICIT.STORE, options)
|
|
73
73
|
}
|
package/src/set-state.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as Internal from "atom.io/internal"
|
|
2
2
|
import type { Canonical } from "atom.io/json"
|
|
3
|
-
import type { Json } from "rel8"
|
|
4
3
|
|
|
5
4
|
import type { WritableFamilyToken, WritableToken } from "."
|
|
6
5
|
|
|
@@ -32,13 +31,17 @@ export function setState<T, K extends Canonical, New extends T, Key extends K>(
|
|
|
32
31
|
): void
|
|
33
32
|
|
|
34
33
|
export function setState<T, New extends T>(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
...params:
|
|
35
|
+
| [
|
|
36
|
+
token: WritableFamilyToken<T, Canonical>,
|
|
37
|
+
key: Canonical,
|
|
38
|
+
value: New | ((oldValue: T) => New),
|
|
39
|
+
]
|
|
40
|
+
| [token: WritableToken<T>, value: New | ((oldValue: T) => New)]
|
|
38
41
|
): void {
|
|
39
|
-
if (
|
|
40
|
-
Internal.setIntoStore(
|
|
42
|
+
if (params.length === 2) {
|
|
43
|
+
Internal.setIntoStore(Internal.IMPLICIT.STORE, ...params)
|
|
41
44
|
} else {
|
|
42
|
-
Internal.setIntoStore(
|
|
45
|
+
Internal.setIntoStore(Internal.IMPLICIT.STORE, ...params)
|
|
43
46
|
}
|
|
44
47
|
}
|
package/src/silo.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { findState } from "atom.io/ephemeral"
|
|
2
|
-
import type { Transceiver } from "atom.io/internal"
|
|
3
2
|
import {
|
|
3
|
+
actUponStore,
|
|
4
|
+
arbitrary,
|
|
4
5
|
createAtomFamily,
|
|
5
6
|
createMoleculeFamily,
|
|
6
7
|
createSelectorFamily,
|
|
@@ -14,33 +15,24 @@ import {
|
|
|
14
15
|
makeMoleculeInStore,
|
|
15
16
|
setIntoStore,
|
|
16
17
|
Store,
|
|
18
|
+
subscribeInStore,
|
|
17
19
|
timeTravel,
|
|
18
20
|
} from "atom.io/internal"
|
|
19
|
-
import type { Canonical, Json } from "atom.io/json"
|
|
20
21
|
|
|
21
22
|
import type {
|
|
22
|
-
AtomToken,
|
|
23
23
|
disposeState,
|
|
24
24
|
getState,
|
|
25
25
|
makeMolecule,
|
|
26
26
|
moleculeFamily,
|
|
27
|
-
MutableAtomFamilyOptions,
|
|
28
|
-
MutableAtomFamilyToken,
|
|
29
|
-
MutableAtomOptions,
|
|
30
|
-
MutableAtomToken,
|
|
31
27
|
redo,
|
|
32
|
-
RegularAtomFamilyOptions,
|
|
33
|
-
RegularAtomFamilyToken,
|
|
34
|
-
RegularAtomOptions,
|
|
35
|
-
RegularAtomToken,
|
|
36
28
|
setState,
|
|
29
|
+
subscribe,
|
|
37
30
|
timeline,
|
|
38
31
|
undo,
|
|
39
32
|
} from "."
|
|
40
|
-
import { subscribe } from "."
|
|
41
33
|
import type { atom, atomFamily } from "./atom"
|
|
42
34
|
import type { selector, selectorFamily } from "./selector"
|
|
43
|
-
import type { transaction } from "./transaction"
|
|
35
|
+
import type { runTransaction, transaction } from "./transaction"
|
|
44
36
|
|
|
45
37
|
export class Silo {
|
|
46
38
|
public store: Store
|
|
@@ -59,62 +51,44 @@ export class Silo {
|
|
|
59
51
|
public redo: typeof redo
|
|
60
52
|
public moleculeFamily: typeof moleculeFamily
|
|
61
53
|
public makeMolecule: typeof makeMolecule
|
|
54
|
+
public runTransaction: typeof runTransaction
|
|
62
55
|
public constructor(config: Store[`config`], fromStore: Store | null = null) {
|
|
63
56
|
const s = new Store(config, fromStore)
|
|
64
|
-
function _atom<T>(options: RegularAtomOptions<T>): RegularAtomToken<T>
|
|
65
|
-
function _atom<T extends Transceiver<any>, J extends Json.Serializable>(
|
|
66
|
-
options: MutableAtomOptions<T, J>,
|
|
67
|
-
): MutableAtomToken<T, J>
|
|
68
|
-
function _atom<T>(
|
|
69
|
-
options: MutableAtomOptions<any, any> | RegularAtomOptions<T>,
|
|
70
|
-
): AtomToken<T> {
|
|
71
|
-
return createStandaloneAtom(options, s)
|
|
72
|
-
}
|
|
73
|
-
function _atomFamily<
|
|
74
|
-
T extends Transceiver<any>,
|
|
75
|
-
J extends Json.Serializable,
|
|
76
|
-
K extends Canonical,
|
|
77
|
-
>(
|
|
78
|
-
options: MutableAtomFamilyOptions<T, J, K>,
|
|
79
|
-
): MutableAtomFamilyToken<T, J, K>
|
|
80
|
-
function _atomFamily<T, K extends Canonical>(
|
|
81
|
-
options: RegularAtomFamilyOptions<T, K>,
|
|
82
|
-
): RegularAtomFamilyToken<T, K>
|
|
83
|
-
function _atomFamily<T, K extends Canonical>(
|
|
84
|
-
options:
|
|
85
|
-
| MutableAtomFamilyOptions<any, any, any>
|
|
86
|
-
| RegularAtomFamilyOptions<T, K>,
|
|
87
|
-
): MutableAtomFamilyToken<any, any, any> | RegularAtomFamilyToken<T, K> {
|
|
88
|
-
return createAtomFamily(options, s)
|
|
89
|
-
}
|
|
90
57
|
this.store = s
|
|
91
|
-
this.atom =
|
|
92
|
-
|
|
93
|
-
this.
|
|
94
|
-
|
|
58
|
+
this.atom = ((options: Parameters<typeof atom>[0]) =>
|
|
59
|
+
createStandaloneAtom(s, options)) as typeof atom
|
|
60
|
+
this.atomFamily = ((options: Parameters<typeof atomFamily>[0]) =>
|
|
61
|
+
createAtomFamily(s, options)) as typeof atomFamily
|
|
62
|
+
this.selector = ((options: Parameters<typeof selector>[0]) =>
|
|
63
|
+
createStandaloneSelector(s, options)) as typeof selector
|
|
64
|
+
this.selectorFamily = ((options: Parameters<typeof selectorFamily>[0]) =>
|
|
65
|
+
createSelectorFamily(s, options)) as typeof selectorFamily
|
|
95
66
|
this.transaction = (options) => createTransaction(options, s)
|
|
96
67
|
this.timeline = (options) => createTimeline(options, s)
|
|
97
|
-
this.findState = (
|
|
68
|
+
this.findState = ((...params: Parameters<typeof findState>) =>
|
|
69
|
+
findInStore(s, ...params)) as typeof findState
|
|
98
70
|
this.getState = ((...params: Parameters<typeof getState>) =>
|
|
99
|
-
getFromStore(...params
|
|
71
|
+
getFromStore(s, ...params)) as typeof getState
|
|
100
72
|
this.setState = ((...params: Parameters<typeof setState>) => {
|
|
101
|
-
setIntoStore(...params
|
|
73
|
+
setIntoStore(s, ...params)
|
|
102
74
|
}) as typeof setState
|
|
103
75
|
this.disposeState = ((...params: Parameters<typeof disposeState>) => {
|
|
104
|
-
disposeFromStore(...params
|
|
76
|
+
disposeFromStore(s, ...params)
|
|
105
77
|
}) as typeof disposeState
|
|
106
|
-
this.subscribe = (
|
|
78
|
+
this.subscribe = ((...params: Parameters<typeof subscribe>) =>
|
|
79
|
+
subscribeInStore(s, ...params)) as typeof subscribe
|
|
107
80
|
this.undo = (token) => {
|
|
108
|
-
timeTravel(`undo`, token
|
|
81
|
+
timeTravel(s, `undo`, token)
|
|
109
82
|
}
|
|
110
83
|
this.redo = (token) => {
|
|
111
|
-
timeTravel(`redo`, token
|
|
84
|
+
timeTravel(s, `redo`, token)
|
|
112
85
|
}
|
|
113
|
-
this.moleculeFamily = ((
|
|
114
|
-
return createMoleculeFamily(
|
|
115
|
-
}) as
|
|
116
|
-
this.makeMolecule = (
|
|
86
|
+
this.moleculeFamily = ((options: Parameters<typeof moleculeFamily>[0]) => {
|
|
87
|
+
return createMoleculeFamily(s, options)
|
|
88
|
+
}) as typeof moleculeFamily
|
|
89
|
+
this.makeMolecule = (...params: Parameters<typeof makeMolecule>) => {
|
|
117
90
|
return makeMoleculeInStore(s, ...params)
|
|
118
|
-
}
|
|
91
|
+
}
|
|
92
|
+
this.runTransaction = (token, id = arbitrary()) => actUponStore(token, id, s)
|
|
119
93
|
}
|
|
120
94
|
}
|
package/src/subscribe.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import type { Flat, Func
|
|
2
|
-
import {
|
|
3
|
-
arbitrary,
|
|
4
|
-
IMPLICIT,
|
|
5
|
-
subscribeToState,
|
|
6
|
-
subscribeToTimeline,
|
|
7
|
-
subscribeToTransaction,
|
|
8
|
-
} from "atom.io/internal"
|
|
1
|
+
import type { Flat, Func } from "atom.io/internal"
|
|
2
|
+
import { arbitrary, IMPLICIT, subscribeInStore } from "atom.io/internal"
|
|
9
3
|
|
|
10
4
|
import type {
|
|
11
5
|
FamilyMetadata,
|
|
@@ -35,35 +29,21 @@ export function subscribe<T>(
|
|
|
35
29
|
token: ReadableToken<T>,
|
|
36
30
|
handleUpdate: UpdateHandler<T>,
|
|
37
31
|
key?: string,
|
|
38
|
-
store?: Store,
|
|
39
32
|
): () => void
|
|
40
33
|
export function subscribe<F extends Func>(
|
|
41
34
|
token: TransactionToken<F>,
|
|
42
35
|
handleUpdate: TransactionUpdateHandler<F>,
|
|
43
36
|
key?: string,
|
|
44
|
-
store?: Store,
|
|
45
37
|
): () => void
|
|
46
38
|
export function subscribe<M extends TimelineManageable>(
|
|
47
39
|
token: TimelineToken<M>,
|
|
48
40
|
handleUpdate: (update: TimelineUpdate<M> | `redo` | `undo`) => void,
|
|
49
41
|
key?: string,
|
|
50
|
-
store?: Store,
|
|
51
42
|
): () => void
|
|
52
43
|
export function subscribe(
|
|
53
44
|
token: ReadableToken<any> | TimelineToken<any> | TransactionToken<any>,
|
|
54
45
|
handleUpdate: (update: any) => void,
|
|
55
46
|
key: string = arbitrary(),
|
|
56
|
-
store = IMPLICIT.STORE,
|
|
57
47
|
): () => void {
|
|
58
|
-
|
|
59
|
-
case `atom`:
|
|
60
|
-
case `mutable_atom`:
|
|
61
|
-
case `readonly_selector`:
|
|
62
|
-
case `selector`:
|
|
63
|
-
return subscribeToState(token, handleUpdate, key, store)
|
|
64
|
-
case `transaction`:
|
|
65
|
-
return subscribeToTransaction(token, handleUpdate, key, store)
|
|
66
|
-
case `timeline`:
|
|
67
|
-
return subscribeToTimeline(token, handleUpdate, key, store)
|
|
68
|
-
}
|
|
48
|
+
return subscribeInStore(IMPLICIT.STORE, token, handleUpdate, key)
|
|
69
49
|
}
|
package/src/timeline.ts
CHANGED
|
@@ -54,9 +54,9 @@ export const timeline = <ManagedAtom extends TimelineManageable>(
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
export const redo = (tl: TimelineToken<any>): void => {
|
|
57
|
-
timeTravel(`redo`, tl
|
|
57
|
+
timeTravel(IMPLICIT.STORE, `redo`, tl)
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export const undo = (tl: TimelineToken<any>): void => {
|
|
61
|
-
timeTravel(`undo`, tl
|
|
61
|
+
timeTravel(IMPLICIT.STORE, `undo`, tl)
|
|
62
62
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AtomEffect } from 'atom.io';
|
|
2
|
+
|
|
3
|
+
type StringInterface<T> = {
|
|
4
|
+
stringify: (t: T) => string;
|
|
5
|
+
parse: (s: string) => T;
|
|
6
|
+
};
|
|
7
|
+
declare const persistSync: <T>(storage: Storage, { stringify, parse }: StringInterface<T>, key: string) => AtomEffect<T>;
|
|
8
|
+
|
|
9
|
+
export { type StringInterface, persistSync };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import '../../dist/chunk-XWL6SNVU.js';
|
|
2
|
+
|
|
3
|
+
// web/src/persist-sync.ts
|
|
4
|
+
var persistSync = (storage, { stringify, parse }, key) => ({ setSelf, onSet }) => {
|
|
3
5
|
const savedValue = storage.getItem(key);
|
|
4
6
|
if (savedValue != null) setSelf(parse(savedValue));
|
|
5
7
|
onSet(({ newValue }) => {
|
|
@@ -10,6 +12,5 @@ var persistAtom = (storage) => ({ stringify, parse }) => (key) => ({ setSelf, on
|
|
|
10
12
|
storage.setItem(key, stringify(newValue));
|
|
11
13
|
});
|
|
12
14
|
};
|
|
13
|
-
var lazyLocalStorageEffect = persistAtom(window.localStorage)(JSON);
|
|
14
15
|
|
|
15
|
-
export {
|
|
16
|
+
export { persistSync };
|