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.
- package/dist/internal/index.d.ts +21 -38
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +82 -263
- package/dist/internal/index.js.map +1 -1
- package/dist/main/index.d.ts +18 -36
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +13 -2
- package/dist/main/index.js.map +1 -1
- package/dist/realtime/index.d.ts +2 -3
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/index.js +1 -1
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime-server/index.js +1 -1
- package/dist/realtime-server/index.js.map +1 -1
- package/dist/realtime-testing/index.js +1 -1
- package/dist/struct/index.d.ts +14 -0
- package/dist/struct/index.d.ts.map +1 -0
- package/dist/struct/index.js +35 -0
- package/dist/struct/index.js.map +1 -0
- package/dist/transceivers/o-list/index.d.ts +10 -6
- package/dist/transceivers/o-list/index.d.ts.map +1 -1
- package/dist/transceivers/o-list/index.js +170 -169
- package/dist/transceivers/o-list/index.js.map +1 -1
- package/dist/transceivers/set-rtx/index.d.ts +1 -0
- package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
- package/dist/transceivers/set-rtx/index.js.map +1 -1
- package/dist/transceivers/u-list/index.d.ts +10 -6
- package/dist/transceivers/u-list/index.d.ts.map +1 -1
- package/dist/transceivers/u-list/index.js +23 -22
- package/dist/transceivers/u-list/index.js.map +1 -1
- package/dist/utility-types-aZkJVERa.d.ts +10 -0
- package/dist/utility-types-aZkJVERa.d.ts.map +1 -0
- package/package.json +13 -9
- package/src/internal/index.ts +0 -1
- package/src/internal/join/create-join.ts +8 -11
- package/src/internal/join/edit-relations-in-store.ts +6 -8
- package/src/internal/join/find-relations-in-store.ts +11 -67
- package/src/internal/join/get-internal-relations-from-store.ts +11 -5
- package/src/internal/join/get-join.ts +7 -9
- package/src/internal/join/join-internal.ts +154 -394
- package/src/internal/mutable/transceiver.ts +1 -5
- package/src/internal/set-state/dispatch-state-update.ts +1 -1
- package/src/internal/store/store.ts +1 -1
- package/src/main/join.ts +68 -151
- package/src/main/realm.ts +4 -4
- package/src/realtime/shared-room-store.ts +5 -15
- package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +1 -1
- package/src/struct/index.ts +1 -0
- package/src/{internal → struct}/micro.ts +1 -1
- package/src/transceivers/o-list/o-list.ts +175 -171
- package/src/transceivers/set-rtx/set-rtx.ts +4 -0
- package/src/transceivers/u-list/u-list.ts +37 -33
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
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<
|
|
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:
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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<
|
|
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:
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
}
|