atom.io 0.29.3 → 0.29.5
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 +18 -94
- package/data/dist/index.js +1 -2
- package/data/src/join.ts +13 -14
- package/dist/{chunk-HH7WBSVS.js → chunk-TCINPEYE.js} +260 -2
- package/internal/dist/index.d.ts +58 -67
- package/internal/dist/index.js +1 -2
- package/internal/src/index.ts +1 -0
- package/internal/src/junction.ts +375 -0
- package/internal/src/store/store.ts +4 -6
- package/internal/src/transaction/build-transaction.ts +1 -2
- package/json/dist/index.js +1 -2
- package/package.json +12 -10
- package/realtime-testing/dist/index.d.ts +2 -2
- package/realtime-testing/dist/index.js +6 -6
- package/realtime-testing/src/setup-realtime-test.tsx +8 -9
- package/dist/chunk-IZXKJOQQ.js +0 -256
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import type { Refinement } from "atom.io/introspection"
|
|
2
|
+
import type { Json } from "atom.io/json"
|
|
3
|
+
|
|
4
|
+
export interface JunctionEntries<Content extends Json.Object | null>
|
|
5
|
+
extends Json.Object {
|
|
6
|
+
readonly relations: [string, string[]][]
|
|
7
|
+
readonly contents: [string, Content][]
|
|
8
|
+
}
|
|
9
|
+
export interface JunctionSchema<ASide extends string, BSide extends string>
|
|
10
|
+
extends Json.Object {
|
|
11
|
+
readonly between: [a: ASide, b: BSide]
|
|
12
|
+
readonly cardinality: `1:1` | `1:n` | `n:n`
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type BaseExternalStoreConfiguration = {
|
|
16
|
+
addRelation: (a: string, b: string) => void
|
|
17
|
+
deleteRelation: (a: string, b: string) => void
|
|
18
|
+
replaceRelationsSafely: (a: string, bs: string[]) => void
|
|
19
|
+
replaceRelationsUnsafely: (a: string, bs: string[]) => void
|
|
20
|
+
getRelatedKeys: (key: string) => Set<string> | undefined
|
|
21
|
+
has: (a: string, b?: string) => boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type ExternalStoreWithContentConfiguration<Content extends Json.Object> =
|
|
25
|
+
{
|
|
26
|
+
getContent: (contentKey: string) => Content | undefined
|
|
27
|
+
setContent: (contentKey: string, content: Content) => void
|
|
28
|
+
deleteContent: (contentKey: string) => void
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type Empty<Obj extends object> = {
|
|
32
|
+
[Key in keyof Obj]?: undefined
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type ExternalStoreConfiguration<Content extends Json.Object | null> =
|
|
36
|
+
Content extends Json.Object
|
|
37
|
+
? BaseExternalStoreConfiguration &
|
|
38
|
+
ExternalStoreWithContentConfiguration<Content>
|
|
39
|
+
: BaseExternalStoreConfiguration &
|
|
40
|
+
Empty<ExternalStoreWithContentConfiguration<Json.Object>>
|
|
41
|
+
|
|
42
|
+
export type JunctionAdvancedConfiguration<Content extends Json.Object | null> = {
|
|
43
|
+
warn?: (...args: any[]) => void
|
|
44
|
+
externalStore?: ExternalStoreConfiguration<Content>
|
|
45
|
+
isContent?: Refinement<unknown, Content>
|
|
46
|
+
makeContentKey?: (a: string, b: string) => string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type JunctionJSON<
|
|
50
|
+
ASide extends string,
|
|
51
|
+
BSide extends string,
|
|
52
|
+
Content extends Json.Object | null,
|
|
53
|
+
> = JunctionEntries<Content> & JunctionSchema<ASide, BSide>
|
|
54
|
+
|
|
55
|
+
export class Junction<
|
|
56
|
+
const ASide extends string,
|
|
57
|
+
const BSide extends string,
|
|
58
|
+
const Content extends Json.Object | null = null,
|
|
59
|
+
> {
|
|
60
|
+
public readonly a: ASide
|
|
61
|
+
public readonly b: BSide
|
|
62
|
+
public readonly cardinality: `1:1` | `1:n` | `n:n`
|
|
63
|
+
public readonly relations = new Map<string, Set<string>>()
|
|
64
|
+
public readonly contents = new Map<string, Content>()
|
|
65
|
+
|
|
66
|
+
public isContent: Refinement<unknown, Content> | null
|
|
67
|
+
public makeContentKey = (a: string, b: string): string => `${a}:${b}`
|
|
68
|
+
|
|
69
|
+
public warn?: (...args: any[]) => void
|
|
70
|
+
|
|
71
|
+
public getRelatedKeys(key: string): Set<string> | undefined {
|
|
72
|
+
return this.relations.get(key)
|
|
73
|
+
}
|
|
74
|
+
protected addRelation(a: string, b: string): void {
|
|
75
|
+
let aRelations = this.relations.get(a)
|
|
76
|
+
let bRelations = this.relations.get(b)
|
|
77
|
+
if (aRelations) {
|
|
78
|
+
aRelations.add(b)
|
|
79
|
+
} else {
|
|
80
|
+
aRelations = new Set([b])
|
|
81
|
+
this.relations.set(a, aRelations)
|
|
82
|
+
}
|
|
83
|
+
if (bRelations) {
|
|
84
|
+
bRelations.add(a)
|
|
85
|
+
} else {
|
|
86
|
+
bRelations = new Set([a])
|
|
87
|
+
this.relations.set(b, bRelations)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
protected deleteRelation(a: string, b: string): void {
|
|
91
|
+
const aRelations = this.relations.get(a)
|
|
92
|
+
if (aRelations) {
|
|
93
|
+
aRelations.delete(b)
|
|
94
|
+
if (aRelations.size === 0) {
|
|
95
|
+
this.relations.delete(a)
|
|
96
|
+
}
|
|
97
|
+
const bRelations = this.relations.get(b)
|
|
98
|
+
if (bRelations) {
|
|
99
|
+
bRelations.delete(a)
|
|
100
|
+
if (bRelations.size === 0) {
|
|
101
|
+
this.relations.delete(b)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
protected replaceRelationsUnsafely(a: string, bs: string[]): void {
|
|
108
|
+
this.relations.set(a, new Set(bs))
|
|
109
|
+
for (const b of bs) {
|
|
110
|
+
const bRelations = new Set([a])
|
|
111
|
+
this.relations.set(b, bRelations)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
protected replaceRelationsSafely(a: string, bs: string[]): void {
|
|
115
|
+
const aRelationsPrev = this.relations.get(a)
|
|
116
|
+
if (aRelationsPrev) {
|
|
117
|
+
for (const b of aRelationsPrev) {
|
|
118
|
+
const bRelations = this.relations.get(b)
|
|
119
|
+
if (bRelations) {
|
|
120
|
+
if (bRelations.size === 1) {
|
|
121
|
+
this.relations.delete(b)
|
|
122
|
+
} else {
|
|
123
|
+
bRelations.delete(a)
|
|
124
|
+
}
|
|
125
|
+
this.contents.delete(this.makeContentKey(a, b))
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
this.relations.set(a, new Set(bs))
|
|
130
|
+
for (const b of bs) {
|
|
131
|
+
let bRelations = this.relations.get(b)
|
|
132
|
+
if (bRelations) {
|
|
133
|
+
bRelations.add(a)
|
|
134
|
+
} else {
|
|
135
|
+
bRelations = new Set([a])
|
|
136
|
+
this.relations.set(b, bRelations)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
protected getContentInternal(contentKey: string): Content | undefined {
|
|
142
|
+
return this.contents.get(contentKey)
|
|
143
|
+
}
|
|
144
|
+
protected setContent(contentKey: string, content: Content): void {
|
|
145
|
+
this.contents.set(contentKey, content)
|
|
146
|
+
}
|
|
147
|
+
protected deleteContent(contentKey: string): void {
|
|
148
|
+
this.contents.delete(contentKey)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public constructor(
|
|
152
|
+
data: JunctionSchema<ASide, BSide> & Partial<JunctionEntries<Content>>,
|
|
153
|
+
config?: JunctionAdvancedConfiguration<Content>,
|
|
154
|
+
) {
|
|
155
|
+
this.a = data.between[0]
|
|
156
|
+
this.b = data.between[1]
|
|
157
|
+
|
|
158
|
+
this.cardinality = data.cardinality
|
|
159
|
+
if (!config?.externalStore) {
|
|
160
|
+
this.relations = new Map(data.relations?.map(([a, b]) => [a, new Set(b)]))
|
|
161
|
+
this.contents = new Map(data.contents)
|
|
162
|
+
}
|
|
163
|
+
this.isContent = config?.isContent ?? null
|
|
164
|
+
if (config?.makeContentKey) {
|
|
165
|
+
this.makeContentKey = config.makeContentKey
|
|
166
|
+
}
|
|
167
|
+
if (config?.externalStore) {
|
|
168
|
+
const externalStore = config.externalStore
|
|
169
|
+
this.has = (a, b) => externalStore.has(a, b)
|
|
170
|
+
this.addRelation = (a, b) => {
|
|
171
|
+
externalStore.addRelation(a, b)
|
|
172
|
+
}
|
|
173
|
+
this.deleteRelation = (a, b) => {
|
|
174
|
+
externalStore.deleteRelation(a, b)
|
|
175
|
+
}
|
|
176
|
+
this.replaceRelationsSafely = (a, bs) => {
|
|
177
|
+
externalStore.replaceRelationsSafely(a, bs)
|
|
178
|
+
}
|
|
179
|
+
this.replaceRelationsUnsafely = (a, bs) => {
|
|
180
|
+
externalStore.replaceRelationsUnsafely(a, bs)
|
|
181
|
+
}
|
|
182
|
+
this.getRelatedKeys = (key) => externalStore.getRelatedKeys(key)
|
|
183
|
+
if (externalStore.getContent) {
|
|
184
|
+
this.getContentInternal = (contentKey) => {
|
|
185
|
+
return externalStore.getContent(contentKey) as any
|
|
186
|
+
}
|
|
187
|
+
this.setContent = (contentKey, content) => {
|
|
188
|
+
externalStore.setContent(contentKey, content as any)
|
|
189
|
+
}
|
|
190
|
+
this.deleteContent = (contentKey) => {
|
|
191
|
+
externalStore.deleteContent(contentKey)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
for (const [x, ys] of data.relations ?? []) {
|
|
195
|
+
for (const y of ys) this.addRelation(x, y)
|
|
196
|
+
}
|
|
197
|
+
for (const [contentKey, content] of data.contents ?? []) {
|
|
198
|
+
this.setContent(contentKey, content)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (config?.warn) {
|
|
202
|
+
this.warn = config.warn
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
public toJSON(): JunctionJSON<ASide, BSide, Content> {
|
|
206
|
+
return {
|
|
207
|
+
between: [this.a, this.b],
|
|
208
|
+
cardinality: this.cardinality,
|
|
209
|
+
relations: [...this.relations.entries()].map(([a, b]) => [a, [...b]]),
|
|
210
|
+
contents: [...this.contents.entries()],
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public set(
|
|
215
|
+
a: string,
|
|
216
|
+
...rest: Content extends null ? [b: string] : [b: string, content: Content]
|
|
217
|
+
): this
|
|
218
|
+
public set(
|
|
219
|
+
relation: { [Key in ASide | BSide]: string },
|
|
220
|
+
...rest: Content extends null ? [] | [b?: undefined] : [content: Content]
|
|
221
|
+
): this
|
|
222
|
+
public set(
|
|
223
|
+
a: string | { [Key in ASide | BSide]: string },
|
|
224
|
+
...rest: Content extends null
|
|
225
|
+
? [] | [b?: string | undefined]
|
|
226
|
+
: [b: string, content: Content] | [content: Content]
|
|
227
|
+
): this {
|
|
228
|
+
const b: string =
|
|
229
|
+
typeof rest[0] === `string`
|
|
230
|
+
? rest[0]
|
|
231
|
+
: (a[this.b as keyof typeof a] as string)
|
|
232
|
+
const content: Content | undefined =
|
|
233
|
+
(rest[1] ?? typeof rest[0] === `string`) ? undefined : (rest[0] as Content)
|
|
234
|
+
a = typeof a === `string` ? a : a[this.a]
|
|
235
|
+
switch (this.cardinality) {
|
|
236
|
+
// biome-ignore lint/suspicious/noFallthroughSwitchClause: perfect here
|
|
237
|
+
case `1:1`: {
|
|
238
|
+
const bPrev = this.getRelatedKey(a)
|
|
239
|
+
if (bPrev && bPrev !== b) this.delete(bPrev, a)
|
|
240
|
+
}
|
|
241
|
+
case `1:n`: {
|
|
242
|
+
const aPrev = this.getRelatedKey(b)
|
|
243
|
+
if (aPrev && aPrev !== a) this.delete(aPrev, b)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (content) {
|
|
247
|
+
const contentKey = this.makeContentKey(a, b)
|
|
248
|
+
this.setContent(contentKey, content)
|
|
249
|
+
}
|
|
250
|
+
this.addRelation(a, b)
|
|
251
|
+
return this
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
public delete(a: string, b?: string): this
|
|
255
|
+
public delete(
|
|
256
|
+
relation:
|
|
257
|
+
| Record<ASide | BSide, string>
|
|
258
|
+
| Record<ASide, string>
|
|
259
|
+
| Record<BSide, string>,
|
|
260
|
+
b?: undefined,
|
|
261
|
+
): this
|
|
262
|
+
public delete(
|
|
263
|
+
x:
|
|
264
|
+
| Record<ASide | BSide, string>
|
|
265
|
+
| Record<ASide, string>
|
|
266
|
+
| Record<BSide, string>
|
|
267
|
+
| string,
|
|
268
|
+
b?: string,
|
|
269
|
+
): this {
|
|
270
|
+
// @ts-expect-error we deduce that this.b may index x
|
|
271
|
+
b = typeof b === `string` ? b : (x[this.b] as string | undefined)
|
|
272
|
+
// @ts-expect-error we deduce that this.a may index x
|
|
273
|
+
const a = typeof x === `string` ? x : (x[this.a] as string | undefined)
|
|
274
|
+
|
|
275
|
+
if (a === undefined && typeof b === `string`) {
|
|
276
|
+
const bRelations = this.getRelatedKeys(b)
|
|
277
|
+
if (bRelations) {
|
|
278
|
+
for (const bRelation of bRelations) {
|
|
279
|
+
this.delete(bRelation, b)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (typeof a === `string` && b === undefined) {
|
|
284
|
+
const aRelations = this.getRelatedKeys(a)
|
|
285
|
+
if (aRelations) {
|
|
286
|
+
for (const aRelation of aRelations) {
|
|
287
|
+
this.delete(a, aRelation)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
if (typeof a === `string` && typeof b === `string`) {
|
|
292
|
+
this.deleteRelation(a, b)
|
|
293
|
+
const contentKey = this.makeContentKey(a, b)
|
|
294
|
+
this.deleteContent(contentKey)
|
|
295
|
+
}
|
|
296
|
+
return this
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
public getRelatedKey(key: string): string | undefined {
|
|
300
|
+
const relations = this.getRelatedKeys(key)
|
|
301
|
+
if (relations) {
|
|
302
|
+
if (relations.size > 1) {
|
|
303
|
+
this.warn?.(
|
|
304
|
+
`${relations.size} related keys were found for key "${key}": (${[
|
|
305
|
+
...relations,
|
|
306
|
+
]
|
|
307
|
+
.map((k) => `"${k}"`)
|
|
308
|
+
.join(`, `)}). Only one related key was expected.`,
|
|
309
|
+
)
|
|
310
|
+
}
|
|
311
|
+
for (const relation of relations) {
|
|
312
|
+
return relation
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
public replaceRelations(
|
|
318
|
+
a: string,
|
|
319
|
+
relations: Content extends null ? string[] : Record<string, Content>,
|
|
320
|
+
config?: { reckless: boolean },
|
|
321
|
+
): this {
|
|
322
|
+
const hasContent = !Array.isArray(relations)
|
|
323
|
+
const bs = hasContent ? Object.keys(relations) : relations
|
|
324
|
+
if (config?.reckless) {
|
|
325
|
+
this.replaceRelationsUnsafely(a, bs)
|
|
326
|
+
} else {
|
|
327
|
+
this.replaceRelationsSafely(a, bs)
|
|
328
|
+
}
|
|
329
|
+
if (hasContent) {
|
|
330
|
+
for (const b of bs) {
|
|
331
|
+
const contentKey = this.makeContentKey(a, b)
|
|
332
|
+
const content = relations[b] as Content
|
|
333
|
+
this.setContent(contentKey, content)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return this
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
public getContent(a: string, b: string): Content | undefined {
|
|
340
|
+
const contentKey = this.makeContentKey(a, b)
|
|
341
|
+
return this.getContentInternal(contentKey)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
public getRelationEntries(
|
|
345
|
+
input: Record<ASide, string> | Record<BSide, string>,
|
|
346
|
+
): [string, Content][] {
|
|
347
|
+
const a: string | undefined = (input as any)[this.a]
|
|
348
|
+
const b: string | undefined = (input as any)[this.b]
|
|
349
|
+
if (a !== undefined && b === undefined) {
|
|
350
|
+
const aRelations = this.getRelatedKeys(a)
|
|
351
|
+
if (aRelations) {
|
|
352
|
+
return [...aRelations].map((aRelation) => {
|
|
353
|
+
return [aRelation, this.getContent(a, aRelation) ?? (null as Content)]
|
|
354
|
+
})
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (a === undefined && b !== undefined) {
|
|
358
|
+
const bRelations = this.getRelatedKeys(b)
|
|
359
|
+
if (bRelations) {
|
|
360
|
+
return [...bRelations].map((bRelation) => {
|
|
361
|
+
return [bRelation, this.getContent(bRelation, b) ?? (null as Content)]
|
|
362
|
+
})
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return []
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
public has(a: string, b?: string): boolean {
|
|
369
|
+
if (b) {
|
|
370
|
+
const setA = this.getRelatedKeys(a)
|
|
371
|
+
return setA?.has(b) ?? false
|
|
372
|
+
}
|
|
373
|
+
return this.relations.has(a)
|
|
374
|
+
}
|
|
375
|
+
}
|
|
@@ -10,22 +10,19 @@ import type {
|
|
|
10
10
|
} from "atom.io"
|
|
11
11
|
import { AtomIOLogger } from "atom.io"
|
|
12
12
|
|
|
13
|
-
import { Junction } from "~/packages/rel8/junction/src"
|
|
14
|
-
|
|
15
13
|
import type {
|
|
16
14
|
Atom,
|
|
17
|
-
Func,
|
|
18
|
-
Molecule,
|
|
19
15
|
MutableAtomFamily,
|
|
20
16
|
ReadonlySelector,
|
|
21
17
|
ReadonlySelectorFamily,
|
|
22
18
|
RegularAtomFamily,
|
|
23
|
-
Tracker,
|
|
24
|
-
Transceiver,
|
|
25
19
|
WritableSelector,
|
|
26
20
|
WritableSelectorFamily,
|
|
27
21
|
} from ".."
|
|
22
|
+
import { Junction } from "../junction"
|
|
28
23
|
import type { Lineage } from "../lineage"
|
|
24
|
+
import type { Molecule } from "../molecule"
|
|
25
|
+
import type { Tracker, Transceiver } from "../mutable"
|
|
29
26
|
import { getJsonToken, getUpdateToken } from "../mutable"
|
|
30
27
|
import type { OperationProgress } from "../operation"
|
|
31
28
|
import { StatefulSubject, Subject } from "../subject"
|
|
@@ -36,6 +33,7 @@ import type {
|
|
|
36
33
|
TransactionProgress,
|
|
37
34
|
} from "../transaction"
|
|
38
35
|
import { isRootStore } from "../transaction"
|
|
36
|
+
import type { Func } from "../utility-types"
|
|
39
37
|
import { CircularBuffer } from "./circular-buffer"
|
|
40
38
|
|
|
41
39
|
export class Store implements Lineage {
|
|
@@ -2,12 +2,11 @@ import type { disposeState, getState, setState } from "atom.io"
|
|
|
2
2
|
import type { findState } from "atom.io/ephemeral"
|
|
3
3
|
import type { seekState } from "atom.io/immortal"
|
|
4
4
|
|
|
5
|
-
import { Junction } from "~/packages/rel8/junction/src"
|
|
6
|
-
|
|
7
5
|
import { arbitrary } from "../arbitrary"
|
|
8
6
|
import { disposeFromStore, findInStore, seekInStore } from "../families"
|
|
9
7
|
import { getEnvironmentData } from "../get-environment-data"
|
|
10
8
|
import { getFromStore } from "../get-state"
|
|
9
|
+
import { Junction } from "../junction"
|
|
11
10
|
import { LazyMap } from "../lazy-map"
|
|
12
11
|
import { newest } from "../lineage"
|
|
13
12
|
import { makeMoleculeInStore } from "../molecule"
|
package/json/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { createWritableSelectorFamily } from '../../dist/chunk-
|
|
2
|
-
import '../../dist/chunk-IZXKJOQQ.js';
|
|
1
|
+
import { createWritableSelectorFamily } from '../../dist/chunk-TCINPEYE.js';
|
|
3
2
|
import '../../dist/chunk-XWL6SNVU.js';
|
|
4
3
|
import { createStandaloneSelector, IMPLICIT, growMoleculeInStore, initFamilyMemberInStore, withdraw, seekInStore } from 'atom.io/internal';
|
|
5
4
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atom.io",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.5",
|
|
4
4
|
"description": "Composable and testable reactive data library.",
|
|
5
5
|
"homepage": "https://atom.io.fyi",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@testing-library/react": "16.0.1",
|
|
56
56
|
"@types/eslint": "9.6.1",
|
|
57
|
-
"@types/estree": "1.0.
|
|
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.8",
|
|
61
61
|
"@types/tmp": "0.2.6",
|
|
62
62
|
"@typescript-eslint/parser": "8.6.0",
|
|
63
63
|
"@typescript-eslint/rule-tester": "8.6.0",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"concurrently": "9.0.1",
|
|
67
67
|
"drizzle-kit": "0.24.2",
|
|
68
68
|
"drizzle-orm": "0.33.0",
|
|
69
|
-
"eslint": "9.
|
|
70
|
-
"framer-motion": "11.5.
|
|
69
|
+
"eslint": "9.11.0",
|
|
70
|
+
"framer-motion": "11.5.6",
|
|
71
71
|
"happy-dom": "15.7.4",
|
|
72
72
|
"http-proxy": "1.18.1",
|
|
73
73
|
"npmlog": "7.0.1",
|
|
@@ -76,15 +76,16 @@
|
|
|
76
76
|
"react": "18.3.1",
|
|
77
77
|
"react-dom": "18.3.1",
|
|
78
78
|
"react-router-dom": "6.26.2",
|
|
79
|
-
"socket.io": "4.
|
|
80
|
-
"socket.io-client": "4.
|
|
79
|
+
"socket.io": "4.8.0",
|
|
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
84
|
"typescript": "5.6.2",
|
|
85
|
-
"vite": "5.4.
|
|
85
|
+
"vite": "5.4.7",
|
|
86
86
|
"vite-tsconfig-paths": "5.0.1",
|
|
87
|
-
"vitest": "2.1.1"
|
|
87
|
+
"vitest": "2.1.1",
|
|
88
|
+
"zod": "3.23.8"
|
|
88
89
|
},
|
|
89
90
|
"main": "dist/index.js",
|
|
90
91
|
"types": "dist/index.d.ts",
|
|
@@ -260,6 +261,7 @@
|
|
|
260
261
|
"test:once": "bun run test:manifest && cross-env IMPORT=dist vitest run",
|
|
261
262
|
"test:once:public": "cross-env IMPORT=dist vitest run public",
|
|
262
263
|
"test:manifest": "tsx __scripts__/manifest-test.node.ts",
|
|
263
|
-
"test:semver": "bun ../break-check/src/break-check.x.ts --verbose"
|
|
264
|
+
"test:semver": "bun ../break-check/src/break-check.x.ts --verbose",
|
|
265
|
+
"postversion": "biome format --write package.json"
|
|
264
266
|
}
|
|
265
267
|
}
|
|
@@ -35,12 +35,12 @@ type RealtimeTestClientBuilder = {
|
|
|
35
35
|
init: () => RealtimeTestClient;
|
|
36
36
|
};
|
|
37
37
|
type RealtimeTestServer = RealtimeTestTools & {
|
|
38
|
-
dispose: () => void
|
|
38
|
+
dispose: () => Promise<void>;
|
|
39
39
|
port: number;
|
|
40
40
|
};
|
|
41
41
|
type RealtimeTestAPI = {
|
|
42
42
|
server: RealtimeTestServer;
|
|
43
|
-
teardown: () => void
|
|
43
|
+
teardown: () => Promise<void>;
|
|
44
44
|
};
|
|
45
45
|
type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {
|
|
46
46
|
client: RealtimeTestClientBuilder;
|
|
@@ -81,8 +81,8 @@ var setupRealtimeTestServer = (options) => {
|
|
|
81
81
|
console.log(`${userKey} disconnected`);
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
|
-
const dispose = () => {
|
|
85
|
-
server.close();
|
|
84
|
+
const dispose = async () => {
|
|
85
|
+
await server.close();
|
|
86
86
|
const roomKeys = getFromStore(silo.store, RT.roomIndex);
|
|
87
87
|
for (const roomKey of roomKeys) {
|
|
88
88
|
const roomState = findInStore(silo.store, RTS.roomSelectors, roomKey);
|
|
@@ -157,8 +157,8 @@ var singleClient = (options) => {
|
|
|
157
157
|
return {
|
|
158
158
|
client,
|
|
159
159
|
server,
|
|
160
|
-
teardown: () => {
|
|
161
|
-
server.dispose();
|
|
160
|
+
teardown: async () => {
|
|
161
|
+
await server.dispose();
|
|
162
162
|
client.dispose();
|
|
163
163
|
}
|
|
164
164
|
};
|
|
@@ -179,8 +179,8 @@ var multiClient = (options) => {
|
|
|
179
179
|
return {
|
|
180
180
|
clients,
|
|
181
181
|
server,
|
|
182
|
-
teardown: () => {
|
|
183
|
-
server.dispose();
|
|
182
|
+
teardown: async () => {
|
|
183
|
+
await server.dispose();
|
|
184
184
|
for (const [, client] of toEntries(clients)) {
|
|
185
185
|
client.dispose();
|
|
186
186
|
}
|
|
@@ -76,14 +76,13 @@ export type RealtimeTestClientBuilder = {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
export type RealtimeTestServer = RealtimeTestTools & {
|
|
79
|
-
dispose: () => void
|
|
79
|
+
dispose: () => Promise<void>
|
|
80
80
|
port: number
|
|
81
|
-
// enableLogging: () => void
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
export type RealtimeTestAPI = {
|
|
85
84
|
server: RealtimeTestServer
|
|
86
|
-
teardown: () => void
|
|
85
|
+
teardown: () => Promise<void>
|
|
87
86
|
}
|
|
88
87
|
export type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {
|
|
89
88
|
client: RealtimeTestClientBuilder
|
|
@@ -152,8 +151,8 @@ export const setupRealtimeTestServer = (
|
|
|
152
151
|
})
|
|
153
152
|
})
|
|
154
153
|
|
|
155
|
-
const dispose = () => {
|
|
156
|
-
server.close()
|
|
154
|
+
const dispose = async () => {
|
|
155
|
+
await server.close()
|
|
157
156
|
const roomKeys = getFromStore(silo.store, RT.roomIndex)
|
|
158
157
|
for (const roomKey of roomKeys) {
|
|
159
158
|
const roomState = findInStore(silo.store, RTS.roomSelectors, roomKey)
|
|
@@ -245,8 +244,8 @@ export const singleClient = (
|
|
|
245
244
|
return {
|
|
246
245
|
client,
|
|
247
246
|
server,
|
|
248
|
-
teardown: () => {
|
|
249
|
-
server.dispose()
|
|
247
|
+
teardown: async () => {
|
|
248
|
+
await server.dispose()
|
|
250
249
|
client.dispose()
|
|
251
250
|
},
|
|
252
251
|
}
|
|
@@ -271,8 +270,8 @@ export const multiClient = <ClientNames extends string>(
|
|
|
271
270
|
return {
|
|
272
271
|
clients,
|
|
273
272
|
server,
|
|
274
|
-
teardown: () => {
|
|
275
|
-
server.dispose()
|
|
273
|
+
teardown: async () => {
|
|
274
|
+
await server.dispose()
|
|
276
275
|
for (const [, client] of toEntries(clients)) {
|
|
277
276
|
client.dispose()
|
|
278
277
|
}
|