atom.io 0.41.0 → 0.42.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.
Files changed (52) hide show
  1. package/dist/internal/index.d.ts +21 -38
  2. package/dist/internal/index.d.ts.map +1 -1
  3. package/dist/internal/index.js +82 -263
  4. package/dist/internal/index.js.map +1 -1
  5. package/dist/main/index.d.ts +18 -36
  6. package/dist/main/index.d.ts.map +1 -1
  7. package/dist/main/index.js +13 -2
  8. package/dist/main/index.js.map +1 -1
  9. package/dist/realtime/index.d.ts +2 -3
  10. package/dist/realtime/index.d.ts.map +1 -1
  11. package/dist/realtime/index.js +1 -1
  12. package/dist/realtime/index.js.map +1 -1
  13. package/dist/realtime-server/index.js +1 -1
  14. package/dist/realtime-server/index.js.map +1 -1
  15. package/dist/realtime-testing/index.js +1 -1
  16. package/dist/struct/index.d.ts +14 -0
  17. package/dist/struct/index.d.ts.map +1 -0
  18. package/dist/struct/index.js +35 -0
  19. package/dist/struct/index.js.map +1 -0
  20. package/dist/transceivers/o-list/index.d.ts +10 -6
  21. package/dist/transceivers/o-list/index.d.ts.map +1 -1
  22. package/dist/transceivers/o-list/index.js +170 -169
  23. package/dist/transceivers/o-list/index.js.map +1 -1
  24. package/dist/transceivers/set-rtx/index.d.ts +1 -0
  25. package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
  26. package/dist/transceivers/set-rtx/index.js.map +1 -1
  27. package/dist/transceivers/u-list/index.d.ts +10 -6
  28. package/dist/transceivers/u-list/index.d.ts.map +1 -1
  29. package/dist/transceivers/u-list/index.js +23 -22
  30. package/dist/transceivers/u-list/index.js.map +1 -1
  31. package/dist/utility-types-aZkJVERa.d.ts +10 -0
  32. package/dist/utility-types-aZkJVERa.d.ts.map +1 -0
  33. package/package.json +13 -9
  34. package/src/internal/index.ts +0 -1
  35. package/src/internal/join/create-join.ts +8 -11
  36. package/src/internal/join/edit-relations-in-store.ts +6 -8
  37. package/src/internal/join/find-relations-in-store.ts +11 -67
  38. package/src/internal/join/get-internal-relations-from-store.ts +11 -5
  39. package/src/internal/join/get-join.ts +7 -9
  40. package/src/internal/join/join-internal.ts +154 -394
  41. package/src/internal/mutable/transceiver.ts +1 -5
  42. package/src/internal/set-state/dispatch-state-update.ts +1 -1
  43. package/src/internal/store/store.ts +1 -1
  44. package/src/main/join.ts +68 -151
  45. package/src/main/realm.ts +4 -4
  46. package/src/realtime/shared-room-store.ts +5 -15
  47. package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +1 -1
  48. package/src/struct/index.ts +1 -0
  49. package/src/{internal → struct}/micro.ts +1 -1
  50. package/src/transceivers/o-list/o-list.ts +175 -171
  51. package/src/transceivers/set-rtx/set-rtx.ts +4 -0
  52. package/src/transceivers/u-list/u-list.ts +37 -33
@@ -1,11 +1,8 @@
1
- import type {
2
- Enumeration,
3
- Fn,
4
- Transceiver,
5
- TransceiverMode,
6
- } from "atom.io/internal"
7
- import { enumeration, packValue, Subject, unpackValue } from "atom.io/internal"
1
+ import type { Fn, Transceiver, TransceiverMode } from "atom.io/internal"
2
+ import { Subject } from "atom.io/internal"
8
3
  import type { primitive } from "atom.io/json"
4
+ import type { Enumeration } from "atom.io/struct"
5
+ import { enumeration, packValue, unpackValue } from "atom.io/struct"
9
6
 
10
7
  export type ArrayMutations = Exclude<keyof Array<any>, keyof ReadonlyArray<any>>
11
8
  export type ArrayUpdate<P extends primitive> =
@@ -95,179 +92,27 @@ true satisfies ArrayUpdate<any>[`type`] extends (typeof ARRAY_UPDATES)[number]
95
92
  export const ARRAY_UPDATE_ENUM: Enumeration<typeof ARRAY_UPDATES> =
96
93
  enumeration(ARRAY_UPDATES)
97
94
 
98
- export function packArrayUpdate<P extends primitive>(
99
- update: ArrayUpdate<P>,
100
- ): PackedArrayUpdate<P> {
101
- let packed = ARRAY_UPDATE_ENUM[update.type] + `\u001F`
102
- switch (update.type) {
103
- case `set`:
104
- packed += update.index + `\u001E` + packValue(update.next)
105
- if (update.prev !== undefined) {
106
- packed += `\u001E` + packValue(update.prev)
107
- }
108
- return packed
109
- case `truncate`:
110
- return (
111
- packed +
112
- update.length +
113
- `\u001E` +
114
- update.items.map(packValue).join(`\u001E`)
115
- )
116
- case `extend`:
117
- return packed + update.next + `\u001E` + update.prev
118
- case `pop`:
119
- case `shift`:
120
- if (update.value !== undefined) {
121
- packed += packValue(update.value)
122
- }
123
- return packed
124
- case `push`:
125
- case `unshift`:
126
- return packed + update.items.map(packValue).join(`\u001E`)
127
- case `copyWithin`:
128
- packed += update.target + `\u001E` + update.start
129
- if (update.end !== undefined) {
130
- packed += `\u001E` + update.end
131
- }
132
- packed += `\u001E\u001E` + update.prev.map(packValue).join(`\u001E`)
133
- return packed
134
- case `fill`:
135
- packed += packValue(update.value)
136
- if (update.start !== undefined) {
137
- packed += `\u001E` + update.start
138
- }
139
- if (update.end !== undefined) {
140
- packed += `\u001E` + update.end
141
- }
142
- packed += `\u001E\u001E` + update.prev.map(packValue).join(`\u001E`)
143
- return packed
144
- case `splice`:
145
- return (
146
- packed +
147
- update.start +
148
- `\u001E\u001E` +
149
- update.deleteCount +
150
- `\u001E\u001E` +
151
- update.items.map(packValue).join(`\u001E`) +
152
- `\u001E\u001E` +
153
- update.deleted.map(packValue).join(`\u001E`)
154
- )
155
- case `reverse`:
156
- return packed
157
- case `sort`:
158
- return (
159
- packed +
160
- update.next.map(packValue).join(`\u001E`) +
161
- `\u001E\u001E` +
162
- update.prev.map(packValue).join(`\u001E`)
163
- )
164
- }
165
- }
166
-
167
- export function unpackArrayUpdate<P extends primitive>(
168
- packed: PackedArrayUpdate<P>,
169
- ): ArrayUpdate<P> {
170
- const [head, tail] = packed.split(`\u001F`) as [
171
- Extract<keyof typeof ARRAY_UPDATE_ENUM, number>,
172
- string,
173
- ]
174
- const type = ARRAY_UPDATE_ENUM[head]
175
- switch (type) {
176
- case `set`: {
177
- const [i, n, p] = tail.split(`\u001E`)
178
- const index = +i
179
- const next = unpackValue(n) as P
180
- if (p === undefined) {
181
- return { type, index, next }
182
- }
183
- const prev = unpackValue(p) as P
184
- return { type, index, next, prev }
185
- }
186
- case `truncate`: {
187
- const [l, ...i] = tail.split(`\u001E`)
188
- const length = +l
189
- const items = i.map(unpackValue) as P[]
190
- return { type, length, items }
191
- }
192
- case `extend`: {
193
- const [n, p] = tail.split(`\u001E`)
194
- const next = +n
195
- const prev = +p
196
- return { type, next, prev }
197
- }
198
- case `pop`:
199
- case `shift`:
200
- if (tail !== ``) {
201
- const value = unpackValue(tail) as P
202
- return { type, value }
203
- }
204
- return { type }
205
- case `push`:
206
- case `unshift`: {
207
- const items = tail.split(`\u001E`).map(unpackValue) as P[]
208
- return { type, items }
209
- }
210
- case `copyWithin`: {
211
- const [numbers, data] = tail.split(`\u001E\u001E`)
212
- const prev = data ? (data.split(`\u001E`).map(unpackValue) as P[]) : []
213
- const [t, s, e] = numbers.split(`\u001E`)
214
- const target = +t
215
- const start = +s
216
- if (e === undefined) {
217
- return { type, target, start, prev }
218
- }
219
- const end = +e
220
- return { type, target, start, prev, end }
221
- }
222
- case `fill`: {
223
- const [numbers, data] = tail.split(`\u001E\u001E`)
224
- const prev = data ? (data.split(`\u001E`).map(unpackValue) as P[]) : []
225
- const [v, s, e] = numbers.split(`\u001E`)
226
- const value = unpackValue(v) as P
227
- if (s === undefined && e === undefined) {
228
- return { type, value, prev }
229
- }
230
- const start = +s
231
- if (e === undefined) {
232
- return { type, value, prev, start }
233
- }
234
- const end = +e
235
- return { type, value, prev, start, end }
236
- }
237
- case `splice`: {
238
- const [s, c, i, d] = tail.split(`\u001E\u001E`)
239
-
240
- const start = +s
241
- const deleteCount = +c
242
- const items = i ? (i.split(`\u001E`).map(unpackValue) as P[]) : []
243
- const deleted = d ? (d.split(`\u001E`).map(unpackValue) as P[]) : []
244
- return { type, start, deleteCount, items, deleted }
245
- }
246
- case `reverse`:
247
- return { type }
248
- case `sort`: {
249
- const [n, p] = tail.split(`\u001E\u001E`)
250
- const next = n ? (n.split(`\u001E`).map(unpackValue) as P[]) : []
251
- const prev = p ? (p.split(`\u001E`).map(unpackValue) as P[]) : []
252
- return { type, next, prev }
253
- }
254
- }
255
- }
256
-
257
95
  export type ArrayMutationHandler = {
258
96
  [K in Exclude<OListUpdateType, `extend` | `set` | `truncate`>]: Fn
259
97
  }
260
98
 
99
+ export type OListView<P extends primitive> = ReadonlyArray<P> & {
100
+ subscribe: (
101
+ key: string,
102
+ fn: (update: PackedArrayUpdate<P>) => void,
103
+ ) => () => void
104
+ }
105
+
261
106
  export class OList<P extends primitive>
262
107
  extends Array<P>
263
108
  implements
264
- Transceiver<ReadonlyArray<P>, PackedArrayUpdate<P>, ReadonlyArray<P>>,
109
+ Transceiver<OListView<P>, PackedArrayUpdate<P>, ReadonlyArray<P>>,
265
110
  ArrayMutationHandler
266
111
  {
267
112
  public mode: TransceiverMode = `record`
268
113
  public readonly subject: Subject<PackedArrayUpdate<P>> = new Subject()
269
114
 
270
- public readonly READONLY_VIEW: ReadonlyArray<P> = this
115
+ public readonly READONLY_VIEW: OListView<P> = this
271
116
 
272
117
  public constructor(arrayLength?: number)
273
118
  public constructor(...items: P[])
@@ -473,7 +318,7 @@ export class OList<P extends primitive>
473
318
  }
474
319
 
475
320
  public emit(update: ArrayUpdate<P>): void {
476
- this.subject.next(packArrayUpdate(update))
321
+ this.subject.next(OList.packUpdate(update))
477
322
  }
478
323
 
479
324
  private doStep(update: ArrayUpdate<P>): void {
@@ -523,7 +368,7 @@ export class OList<P extends primitive>
523
368
 
524
369
  public do(update: PackedArrayUpdate<P>): null {
525
370
  this.mode = `playback`
526
- const unpacked = unpackArrayUpdate(update)
371
+ const unpacked = OList.unpackUpdate(update)
527
372
  this.doStep(unpacked)
528
373
  this.mode = `record`
529
374
  return null
@@ -605,9 +450,168 @@ export class OList<P extends primitive>
605
450
 
606
451
  public undo(update: PackedArrayUpdate<P>): number | null {
607
452
  this.mode = `playback`
608
- const unpacked = unpackArrayUpdate(update)
453
+ const unpacked = OList.unpackUpdate(update)
609
454
  this.undoStep(unpacked)
610
455
  this.mode = `record`
611
456
  return null
612
457
  }
458
+
459
+ public static packUpdate<P extends primitive>(
460
+ update: ArrayUpdate<P>,
461
+ ): PackedArrayUpdate<P> {
462
+ let packed = ARRAY_UPDATE_ENUM[update.type] + `\u001F`
463
+ switch (update.type) {
464
+ case `set`:
465
+ packed += update.index + `\u001E` + packValue(update.next)
466
+ if (update.prev !== undefined) {
467
+ packed += `\u001E` + packValue(update.prev)
468
+ }
469
+ return packed
470
+ case `truncate`:
471
+ return (
472
+ packed +
473
+ update.length +
474
+ `\u001E` +
475
+ update.items.map(packValue).join(`\u001E`)
476
+ )
477
+ case `extend`:
478
+ return packed + update.next + `\u001E` + update.prev
479
+ case `pop`:
480
+ case `shift`:
481
+ if (update.value !== undefined) {
482
+ packed += packValue(update.value)
483
+ }
484
+ return packed
485
+ case `push`:
486
+ case `unshift`:
487
+ return packed + update.items.map(packValue).join(`\u001E`)
488
+ case `copyWithin`:
489
+ packed += update.target + `\u001E` + update.start
490
+ if (update.end !== undefined) {
491
+ packed += `\u001E` + update.end
492
+ }
493
+ packed += `\u001E\u001E` + update.prev.map(packValue).join(`\u001E`)
494
+ return packed
495
+ case `fill`:
496
+ packed += packValue(update.value)
497
+ if (update.start !== undefined) {
498
+ packed += `\u001E` + update.start
499
+ }
500
+ if (update.end !== undefined) {
501
+ packed += `\u001E` + update.end
502
+ }
503
+ packed += `\u001E\u001E` + update.prev.map(packValue).join(`\u001E`)
504
+ return packed
505
+ case `splice`:
506
+ return (
507
+ packed +
508
+ update.start +
509
+ `\u001E\u001E` +
510
+ update.deleteCount +
511
+ `\u001E\u001E` +
512
+ update.items.map(packValue).join(`\u001E`) +
513
+ `\u001E\u001E` +
514
+ update.deleted.map(packValue).join(`\u001E`)
515
+ )
516
+ case `reverse`:
517
+ return packed
518
+ case `sort`:
519
+ return (
520
+ packed +
521
+ update.next.map(packValue).join(`\u001E`) +
522
+ `\u001E\u001E` +
523
+ update.prev.map(packValue).join(`\u001E`)
524
+ )
525
+ }
526
+ }
527
+
528
+ public static unpackUpdate<P extends primitive>(
529
+ packed: PackedArrayUpdate<P>,
530
+ ): ArrayUpdate<P> {
531
+ const [head, tail] = packed.split(`\u001F`) as [
532
+ Extract<keyof typeof ARRAY_UPDATE_ENUM, number>,
533
+ string,
534
+ ]
535
+ const type = ARRAY_UPDATE_ENUM[head]
536
+ switch (type) {
537
+ case `set`: {
538
+ const [i, n, p] = tail.split(`\u001E`)
539
+ const index = +i
540
+ const next = unpackValue(n) as P
541
+ if (p === undefined) {
542
+ return { type, index, next }
543
+ }
544
+ const prev = unpackValue(p) as P
545
+ return { type, index, next, prev }
546
+ }
547
+ case `truncate`: {
548
+ const [l, ...i] = tail.split(`\u001E`)
549
+ const length = +l
550
+ const items = i.map(unpackValue) as P[]
551
+ return { type, length, items }
552
+ }
553
+ case `extend`: {
554
+ const [n, p] = tail.split(`\u001E`)
555
+ const next = +n
556
+ const prev = +p
557
+ return { type, next, prev }
558
+ }
559
+ case `pop`:
560
+ case `shift`:
561
+ if (tail !== ``) {
562
+ const value = unpackValue(tail) as P
563
+ return { type, value }
564
+ }
565
+ return { type }
566
+ case `push`:
567
+ case `unshift`: {
568
+ const items = tail.split(`\u001E`).map(unpackValue) as P[]
569
+ return { type, items }
570
+ }
571
+ case `copyWithin`: {
572
+ const [numbers, data] = tail.split(`\u001E\u001E`)
573
+ const prev = data ? (data.split(`\u001E`).map(unpackValue) as P[]) : []
574
+ const [t, s, e] = numbers.split(`\u001E`)
575
+ const target = +t
576
+ const start = +s
577
+ if (e === undefined) {
578
+ return { type, target, start, prev }
579
+ }
580
+ const end = +e
581
+ return { type, target, start, prev, end }
582
+ }
583
+ case `fill`: {
584
+ const [numbers, data] = tail.split(`\u001E\u001E`)
585
+ const prev = data ? (data.split(`\u001E`).map(unpackValue) as P[]) : []
586
+ const [v, s, e] = numbers.split(`\u001E`)
587
+ const value = unpackValue(v) as P
588
+ if (s === undefined && e === undefined) {
589
+ return { type, value, prev }
590
+ }
591
+ const start = +s
592
+ if (e === undefined) {
593
+ return { type, value, prev, start }
594
+ }
595
+ const end = +e
596
+ return { type, value, prev, start, end }
597
+ }
598
+ case `splice`: {
599
+ const [s, c, i, d] = tail.split(`\u001E\u001E`)
600
+
601
+ const start = +s
602
+ const deleteCount = +c
603
+ const items = i ? (i.split(`\u001E`).map(unpackValue) as P[]) : []
604
+ const deleted = d ? (d.split(`\u001E`).map(unpackValue) as P[]) : []
605
+ return { type, start, deleteCount, items, deleted }
606
+ }
607
+ case `reverse`:
608
+ return { type }
609
+ case `sort`: {
610
+ const [n, p] = tail.split(`\u001E\u001E`)
611
+ const next = n ? (n.split(`\u001E`).map(unpackValue) as P[]) : []
612
+ const prev = p ? (p.split(`\u001E`).map(unpackValue) as P[]) : []
613
+ return { type, next, prev }
614
+ }
615
+ }
616
+ }
613
617
  }
@@ -12,6 +12,10 @@ export interface SetRTXView<P extends primitive> extends ReadonlySet<P> {
12
12
  readonly cacheLimit: number
13
13
  readonly cacheIdx: number
14
14
  readonly cacheUpdateNumber: number
15
+ readonly subscribe: (
16
+ key: string,
17
+ fn: (update: NumberedSetUpdateString) => void,
18
+ ) => () => void
15
19
  }
16
20
 
17
21
  export interface SetRTXJson<P extends primitive> extends Json.Object {
@@ -1,11 +1,8 @@
1
- import type {
2
- Enumeration,
3
- Fn,
4
- Transceiver,
5
- TransceiverMode,
6
- } from "atom.io/internal"
7
- import { enumeration, packValue, Subject, unpackValue } from "atom.io/internal"
1
+ import type { Fn, Transceiver, TransceiverMode } from "atom.io/internal"
2
+ import { Subject } from "atom.io/internal"
8
3
  import type { primitive } from "atom.io/json"
4
+ import type { Enumeration } from "atom.io/struct"
5
+ import { enumeration, packValue, unpackValue } from "atom.io/struct"
9
6
 
10
7
  export type SetMutations = Exclude<
11
8
  keyof Set<any>,
@@ -32,33 +29,19 @@ export type PackedSetUpdate<P extends primitive> = string & {
32
29
  export const SET_UPDATE_ENUM: Enumeration<[`add`, `delete`, `clear`]> =
33
30
  enumeration([`add`, `delete`, `clear`] as const)
34
31
 
35
- export function packSetUpdate<P extends primitive>(
36
- update: SetUpdate<P>,
37
- ): PackedSetUpdate<P> {
38
- const head = SET_UPDATE_ENUM[update.type] + `\u001F`
39
- if (update.type === `clear`) {
40
- return head + update.values.map(packValue).join(`\u001E`)
41
- }
42
- return head + packValue(update.value)
43
- }
44
- export function unpackSetUpdate<P extends primitive>(
45
- packed: PackedSetUpdate<P>,
46
- ): SetUpdate<P> {
47
- const [type, tail] = packed.split(`\u001F`) as [0 | 1 | 2, string]
48
- const head = SET_UPDATE_ENUM[type]
49
- if (head === `clear`) {
50
- const values = tail.split(`\u001E`).map(unpackValue) as P[]
51
- return { type: `clear`, values }
52
- }
53
- return { type: head, value: unpackValue(tail) as P }
54
- }
55
-
56
32
  export type SetMutationHandler = { [K in UListUpdateType]: Fn }
57
33
 
34
+ export type UListView<P extends primitive> = ReadonlySet<P> & {
35
+ subscribe: (
36
+ key: string,
37
+ fn: (update: PackedSetUpdate<P>) => void,
38
+ ) => () => void
39
+ }
40
+
58
41
  export class UList<P extends primitive>
59
42
  extends Set<P>
60
43
  implements
61
- Transceiver<ReadonlySet<P>, PackedSetUpdate<P>, ReadonlyArray<P>>,
44
+ Transceiver<UListView<P>, PackedSetUpdate<P>, ReadonlyArray<P>>,
62
45
  SetMutationHandler
63
46
  {
64
47
  public mode: TransceiverMode = `record`
@@ -70,7 +53,7 @@ export class UList<P extends primitive>
70
53
  }
71
54
  }
72
55
 
73
- public readonly READONLY_VIEW: ReadonlySet<P> = this
56
+ public readonly READONLY_VIEW: UListView<P> = this
74
57
 
75
58
  public toJSON(): ReadonlyArray<P> {
76
59
  return [...this]
@@ -112,12 +95,12 @@ export class UList<P extends primitive>
112
95
  }
113
96
 
114
97
  public emit(update: SetUpdate<P>): void {
115
- this.subject.next(packSetUpdate(update))
98
+ this.subject.next(UList.packUpdate(update))
116
99
  }
117
100
 
118
101
  public do(packed: PackedSetUpdate<P>): null {
119
102
  this.mode = `playback`
120
- const update = unpackSetUpdate(packed)
103
+ const update = UList.unpackUpdate(packed)
121
104
  switch (update.type) {
122
105
  case `add`:
123
106
  this.add(update.value)
@@ -133,7 +116,7 @@ export class UList<P extends primitive>
133
116
  }
134
117
 
135
118
  public undo(packed: PackedSetUpdate<P>): number | null {
136
- const update = unpackSetUpdate(packed)
119
+ const update = UList.unpackUpdate(packed)
137
120
  this.mode = `playback`
138
121
  switch (update.type) {
139
122
  case `add`:
@@ -150,4 +133,25 @@ export class UList<P extends primitive>
150
133
  this.mode = `record`
151
134
  return null
152
135
  }
136
+
137
+ public static packUpdate<P extends primitive>(
138
+ update: SetUpdate<P>,
139
+ ): PackedSetUpdate<P> {
140
+ const head = SET_UPDATE_ENUM[update.type] + `\u001F`
141
+ if (update.type === `clear`) {
142
+ return head + update.values.map(packValue).join(`\u001E`)
143
+ }
144
+ return head + packValue(update.value)
145
+ }
146
+ public static unpackUpdate<P extends primitive>(
147
+ packed: PackedSetUpdate<P>,
148
+ ): SetUpdate<P> {
149
+ const [type, tail] = packed.split(`\u001F`) as [0 | 1 | 2, string]
150
+ const head = SET_UPDATE_ENUM[type]
151
+ if (head === `clear`) {
152
+ const values = tail.split(`\u001E`).map(unpackValue) as P[]
153
+ return { type: `clear`, values }
154
+ }
155
+ return { type: head, value: unpackValue(tail) as P }
156
+ }
153
157
  }