atom.io 0.40.9 → 0.41.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 (32) hide show
  1. package/dist/eslint-plugin/index.js +1 -1
  2. package/dist/internal/index.d.ts +11 -2
  3. package/dist/internal/index.d.ts.map +1 -1
  4. package/dist/internal/index.js +34 -1
  5. package/dist/internal/index.js.map +1 -1
  6. package/dist/realtime/index.d.ts +2 -1
  7. package/dist/realtime/index.d.ts.map +1 -1
  8. package/dist/realtime/index.js.map +1 -1
  9. package/dist/realtime-client/index.js +2 -1
  10. package/dist/realtime-client/index.js.map +1 -1
  11. package/dist/realtime-server/index.js +1 -1
  12. package/dist/realtime-server/index.js.map +1 -1
  13. package/dist/transceivers/o-list/index.d.ts +87 -0
  14. package/dist/transceivers/o-list/index.d.ts.map +1 -0
  15. package/dist/transceivers/o-list/index.js +513 -0
  16. package/dist/transceivers/o-list/index.js.map +1 -0
  17. package/dist/transceivers/set-rtx/index.d.ts +16 -16
  18. package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
  19. package/dist/transceivers/set-rtx/index.js.map +1 -1
  20. package/dist/transceivers/u-list/index.d.ts +27 -18
  21. package/dist/transceivers/u-list/index.d.ts.map +1 -1
  22. package/dist/transceivers/u-list/index.js +54 -34
  23. package/dist/transceivers/u-list/index.js.map +1 -1
  24. package/package.json +17 -13
  25. package/src/internal/index.ts +1 -0
  26. package/src/internal/micro.ts +69 -0
  27. package/src/realtime/shared-room-store.ts +3 -2
  28. package/src/realtime-server/ipc-sockets/parent-socket.ts +1 -1
  29. package/src/transceivers/o-list/index.ts +1 -0
  30. package/src/transceivers/o-list/o-list.ts +613 -0
  31. package/src/transceivers/set-rtx/set-rtx.ts +22 -21
  32. package/src/transceivers/u-list/u-list.ts +85 -55
@@ -4,11 +4,11 @@ import type { Json, primitive } from "atom.io/json"
4
4
  import { stringifyJson } from "atom.io/json"
5
5
 
6
6
  export type SetUpdateType = `add` | `clear` | `del` | `tx`
7
- export type SetUpdate = `${SetUpdateType}:${string}`
8
- export type NumberedSetUpdate = `${number | `*`}=${SetUpdate}`
7
+ export type SetUpdateString = `${SetUpdateType}:${string}`
8
+ export type NumberedSetUpdateString = `${number | `*`}=${SetUpdateString}`
9
9
 
10
10
  export interface SetRTXView<P extends primitive> extends ReadonlySet<P> {
11
- readonly cache: ReadonlyArray<NumberedSetUpdate | null>
11
+ readonly cache: ReadonlyArray<NumberedSetUpdateString | null>
12
12
  readonly cacheLimit: number
13
13
  readonly cacheIdx: number
14
14
  readonly cacheUpdateNumber: number
@@ -16,7 +16,7 @@ export interface SetRTXView<P extends primitive> extends ReadonlySet<P> {
16
16
 
17
17
  export interface SetRTXJson<P extends primitive> extends Json.Object {
18
18
  members: P[]
19
- cache: (NumberedSetUpdate | null)[]
19
+ cache: (NumberedSetUpdateString | null)[]
20
20
  cacheLimit: number
21
21
  cacheIdx: number
22
22
  cacheUpdateNumber: number
@@ -24,13 +24,14 @@ export interface SetRTXJson<P extends primitive> extends Json.Object {
24
24
  export class SetRTX<P extends primitive>
25
25
  extends Set<P>
26
26
  implements
27
- Transceiver<SetRTXView<P>, NumberedSetUpdate, SetRTXJson<P>>,
27
+ Transceiver<SetRTXView<P>, NumberedSetUpdateString, SetRTXJson<P>>,
28
28
  Lineage
29
29
  {
30
30
  public mode: TransceiverMode = `record`
31
- public readonly subject: Subject<SetUpdate> = new Subject<SetUpdate>()
31
+ public readonly subject: Subject<SetUpdateString> =
32
+ new Subject<SetUpdateString>()
32
33
  public cacheLimit = 0
33
- public cache: (NumberedSetUpdate | null)[] = []
34
+ public cache: (NumberedSetUpdateString | null)[] = []
34
35
  public cacheIdx = -1
35
36
  public cacheUpdateNumber = -1
36
37
 
@@ -100,7 +101,7 @@ export class SetRTX<P extends primitive>
100
101
 
101
102
  public readonly parent: SetRTX<P> | null = null
102
103
  public child: SetRTX<P> | null = null
103
- public transactionUpdates: SetUpdate[] | null = null
104
+ public transactionUpdates: SetUpdateString[] | null = null
104
105
  public transaction(run: (child: SetRTX<P>) => boolean): void {
105
106
  this.mode = `transaction`
106
107
  this.transactionUpdates = []
@@ -134,24 +135,24 @@ export class SetRTX<P extends primitive>
134
135
 
135
136
  protected _subscribe(
136
137
  key: string,
137
- fn: (update: SetUpdate) => void,
138
+ fn: (update: SetUpdateString) => void,
138
139
  ): () => void {
139
140
  return this.subject.subscribe(key, fn)
140
141
  }
141
142
  public subscribe(
142
143
  key: string,
143
- fn: (update: NumberedSetUpdate) => void,
144
+ fn: (update: NumberedSetUpdateString) => void,
144
145
  ): () => void {
145
146
  return this.subject.subscribe(key, (update) => {
146
147
  fn(`${this.cacheUpdateNumber}=${update}`)
147
148
  })
148
149
  }
149
150
 
150
- public emit(update: SetUpdate): void {
151
+ public emit(update: SetUpdateString): void {
151
152
  this.subject.next(update)
152
153
  }
153
154
 
154
- private doStep(update: SetUpdate): void {
155
+ private doStep(update: SetUpdateString): void {
155
156
  const typeValueBreak = update.indexOf(`:`)
156
157
  const type = update.substring(0, typeValueBreak) as SetUpdateType
157
158
  const value = update.substring(typeValueBreak + 1)
@@ -167,17 +168,17 @@ export class SetRTX<P extends primitive>
167
168
  break
168
169
  case `tx`:
169
170
  for (const subUpdate of value.split(`;`)) {
170
- this.doStep(subUpdate as SetUpdate)
171
+ this.doStep(subUpdate as SetUpdateString)
171
172
  }
172
173
  }
173
174
  }
174
175
 
175
- public getUpdateNumber(update: NumberedSetUpdate): number {
176
+ public getUpdateNumber(update: NumberedSetUpdateString): number {
176
177
  const breakpoint = update.indexOf(`=`)
177
178
  return Number(update.substring(0, breakpoint))
178
179
  }
179
180
 
180
- public do(update: NumberedSetUpdate): number | `OUT_OF_RANGE` | null {
181
+ public do(update: NumberedSetUpdateString): number | `OUT_OF_RANGE` | null {
181
182
  const breakpoint = update.indexOf(`=`)
182
183
  const updateNumber = Number(update.substring(0, breakpoint))
183
184
  const eventOffset = updateNumber - this.cacheUpdateNumber
@@ -185,7 +186,7 @@ export class SetRTX<P extends primitive>
185
186
  if (isFuture || Number.isNaN(eventOffset)) {
186
187
  if (eventOffset === 1 || Number.isNaN(eventOffset)) {
187
188
  this.mode = `playback`
188
- const innerUpdate = update.substring(breakpoint + 1) as SetUpdate
189
+ const innerUpdate = update.substring(breakpoint + 1) as SetUpdateString
189
190
  this.doStep(innerUpdate)
190
191
  this.mode = `record`
191
192
  this.cacheUpdateNumber = updateNumber
@@ -211,7 +212,7 @@ export class SetRTX<P extends primitive>
211
212
  this.undo(u)
212
213
  done = this.cacheIdx === eventIdx - 1
213
214
  }
214
- const innerUpdate = update.substring(breakpoint + 1) as SetUpdate
215
+ const innerUpdate = update.substring(breakpoint + 1) as SetUpdateString
215
216
  this.doStep(innerUpdate)
216
217
  this.mode = `record`
217
218
  this.cacheUpdateNumber = updateNumber
@@ -220,7 +221,7 @@ export class SetRTX<P extends primitive>
220
221
  return `OUT_OF_RANGE`
221
222
  }
222
223
 
223
- public undoStep(update: SetUpdate): void {
224
+ public undoStep(update: SetUpdateString): void {
224
225
  const breakpoint = update.indexOf(`:`)
225
226
  const type = update.substring(0, breakpoint) as SetUpdateType
226
227
  const value = update.substring(breakpoint + 1)
@@ -237,7 +238,7 @@ export class SetRTX<P extends primitive>
237
238
  break
238
239
  }
239
240
  case `tx`: {
240
- const updates = value.split(`;`) as SetUpdate[]
241
+ const updates = value.split(`;`) as SetUpdateString[]
241
242
  for (let i = updates.length - 1; i >= 0; i--) {
242
243
  this.undoStep(updates[i])
243
244
  }
@@ -245,12 +246,12 @@ export class SetRTX<P extends primitive>
245
246
  }
246
247
  }
247
248
 
248
- public undo(update: NumberedSetUpdate): number | null {
249
+ public undo(update: NumberedSetUpdateString): number | null {
249
250
  const breakpoint = update.indexOf(`=`)
250
251
  const updateNumber = Number(update.substring(0, breakpoint))
251
252
  if (updateNumber === this.cacheUpdateNumber) {
252
253
  this.mode = `playback`
253
- const innerUpdate = update.substring(breakpoint + 1) as SetUpdate
254
+ const innerUpdate = update.substring(breakpoint + 1) as SetUpdateString
254
255
  this.undoStep(innerUpdate)
255
256
  this.mode = `record`
256
257
  this.cacheUpdateNumber--
@@ -1,24 +1,68 @@
1
- import type { Transceiver, TransceiverMode } from "atom.io/internal"
2
- import { Subject } from "atom.io/internal"
3
- import type { Json, primitive, stringified } from "atom.io/json"
4
- import { stringifyJson } from "atom.io/json"
5
-
6
- export type UListUpdateType = `add` | `clear` | `del`
7
- export type UListUpdate<P extends primitive> =
8
- | `${`add` | `del`}:${stringified<P>}`
9
- | `clear:${stringified<P[]>}`
10
-
11
- export interface UListJson<P extends primitive> extends Json.Object {
12
- members: P[]
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"
8
+ import type { primitive } from "atom.io/json"
9
+
10
+ export type SetMutations = Exclude<
11
+ keyof Set<any>,
12
+ symbol | keyof ReadonlySet<any>
13
+ >
14
+ export type SetUpdate<P extends primitive> =
15
+ | {
16
+ type: `add` | `delete`
17
+ value: P
18
+ }
19
+ | {
20
+ type: `clear`
21
+ values: P[]
22
+ }
23
+ export type UListUpdateType = SetUpdate<any>[`type`]
24
+ true satisfies SetMutations extends UListUpdateType
25
+ ? true
26
+ : Exclude<SetMutations, UListUpdateType>
27
+
28
+ export type PackedSetUpdate<P extends primitive> = string & {
29
+ update?: SetUpdate<P>
30
+ }
31
+
32
+ export const SET_UPDATE_ENUM: Enumeration<[`add`, `delete`, `clear`]> =
33
+ enumeration([`add`, `delete`, `clear`] as const)
34
+
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 }
13
54
  }
55
+
56
+ export type SetMutationHandler = { [K in UListUpdateType]: Fn }
57
+
14
58
  export class UList<P extends primitive>
15
59
  extends Set<P>
16
- implements Transceiver<ReadonlySet<P>, UListUpdate<P>, UListJson<P>>
60
+ implements
61
+ Transceiver<ReadonlySet<P>, PackedSetUpdate<P>, ReadonlyArray<P>>,
62
+ SetMutationHandler
17
63
  {
18
64
  public mode: TransceiverMode = `record`
19
- public readonly subject: Subject<UListUpdate<P>> = new Subject<
20
- UListUpdate<P>
21
- >()
65
+ public readonly subject: Subject<PackedSetUpdate<P>> = new Subject()
22
66
 
23
67
  public constructor(values?: Iterable<P>) {
24
68
  super(values)
@@ -28,20 +72,18 @@ export class UList<P extends primitive>
28
72
 
29
73
  public readonly READONLY_VIEW: ReadonlySet<P> = this
30
74
 
31
- public toJSON(): UListJson<P> {
32
- return {
33
- members: [...this],
34
- }
75
+ public toJSON(): ReadonlyArray<P> {
76
+ return [...this]
35
77
  }
36
78
 
37
- public static fromJSON<P extends primitive>(json: UListJson<P>): UList<P> {
38
- return new UList<P>(json.members)
79
+ public static fromJSON<P extends primitive>(json: ReadonlyArray<P>): UList<P> {
80
+ return new UList<P>(json)
39
81
  }
40
82
 
41
83
  public add(value: P): this {
42
84
  const result = super.add(value)
43
85
  if (this.mode === `record`) {
44
- this.emit(`add:${stringifyJson<P>(value)}`)
86
+ this.emit({ type: `add`, value })
45
87
  }
46
88
  return result
47
89
  }
@@ -50,73 +92,61 @@ export class UList<P extends primitive>
50
92
  const capturedContents = this.mode === `record` ? [...this] : null
51
93
  super.clear()
52
94
  if (capturedContents) {
53
- this.emit(`clear:${stringifyJson(capturedContents)}`)
95
+ this.emit({ type: `clear`, values: capturedContents })
54
96
  }
55
97
  }
56
98
 
57
99
  public delete(value: P): boolean {
58
100
  const result = super.delete(value)
59
101
  if (this.mode === `record`) {
60
- this.emit(`del:${stringifyJson<P>(value)}`)
102
+ this.emit({ type: `delete`, value })
61
103
  }
62
104
  return result
63
105
  }
64
106
 
65
107
  public subscribe(
66
108
  key: string,
67
- fn: (update: UListUpdate<P>) => void,
109
+ fn: (update: PackedSetUpdate<P>) => void,
68
110
  ): () => void {
69
111
  return this.subject.subscribe(key, fn)
70
112
  }
71
113
 
72
- public emit(update: UListUpdate<P>): void {
73
- this.subject.next(update)
114
+ public emit(update: SetUpdate<P>): void {
115
+ this.subject.next(packSetUpdate(update))
74
116
  }
75
117
 
76
- private doStep(update: UListUpdate<P>): void {
77
- const typeValueBreak = update.indexOf(`:`)
78
- const type = update.substring(0, typeValueBreak) as UListUpdateType
79
- const value = update.substring(typeValueBreak + 1)
80
- switch (type) {
118
+ public do(packed: PackedSetUpdate<P>): null {
119
+ this.mode = `playback`
120
+ const update = unpackSetUpdate(packed)
121
+ switch (update.type) {
81
122
  case `add`:
82
- this.add(JSON.parse(value))
123
+ this.add(update.value)
83
124
  break
84
- case `del`:
85
- this.delete(JSON.parse(value))
125
+ case `delete`:
126
+ this.delete(update.value)
86
127
  break
87
128
  case `clear`:
88
129
  this.clear()
89
130
  }
90
- }
91
-
92
- public do(update: UListUpdate<P>): null {
93
- this.mode = `playback`
94
- this.doStep(update)
95
131
  this.mode = `record`
96
132
  return null
97
133
  }
98
134
 
99
- public undoStep(update: UListUpdate<P>): void {
100
- const breakpoint = update.indexOf(`:`)
101
- const type = update.substring(0, breakpoint) as UListUpdateType
102
- const value = update.substring(breakpoint + 1)
103
- switch (type) {
135
+ public undo(packed: PackedSetUpdate<P>): number | null {
136
+ const update = unpackSetUpdate(packed)
137
+ this.mode = `playback`
138
+ switch (update.type) {
104
139
  case `add`:
105
- this.delete(JSON.parse(value))
140
+ this.delete(update.value)
106
141
  break
107
- case `del`:
108
- this.add(JSON.parse(value))
142
+ case `delete`:
143
+ this.add(update.value)
109
144
  break
110
145
  case `clear`: {
111
- const values = JSON.parse(value) as P[]
146
+ const values = update.values
112
147
  for (const v of values) this.add(v)
113
148
  }
114
149
  }
115
- }
116
-
117
- public undo(update: UListUpdate<P>): number | null {
118
- this.mode = `playback`
119
- this.undoStep(update)
120
150
  this.mode = `record`
121
151
  return null
122
152
  }