@pluv/client 5.0.1 → 5.0.3

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/eslint.config.mjs DELETED
@@ -1,4 +0,0 @@
1
- import { config } from "eslint-config-pluv/base";
2
-
3
- /** @type {import("eslint").Linter.Config} */
4
- export default config;
@@ -1,19 +0,0 @@
1
- export abstract class AbstractStorageStore {
2
- public room: string;
3
-
4
- constructor(room: string) {
5
- this.room = room;
6
- }
7
-
8
- public abstract addUpdate(update: string): Promise<void>;
9
-
10
- public abstract destroy(): Promise<void>;
11
-
12
- public abstract flatten(encodedState: string): Promise<void>;
13
-
14
- public abstract getShouldFlatten(): Promise<boolean>;
15
-
16
- public abstract getUpdates(start?: number): Promise<readonly string[]>;
17
-
18
- public abstract initialize(): Promise<void>;
19
- }
@@ -1,119 +0,0 @@
1
- import type { AbstractCrdtDocFactory, InferDocLike, InferStorage } from "@pluv/crdt";
2
- import { noop } from "@pluv/crdt";
3
-
4
- export type CrdtManagerOptions<TCrdt extends AbstractCrdtDocFactory<any, any>> = {
5
- initialStorage?: TCrdt;
6
- };
7
-
8
- interface CrdtManagerInitializeParams {
9
- origin?: any;
10
- update: string | readonly string[];
11
- }
12
-
13
- interface ApplyUpdateParams {
14
- origin?: any;
15
- update: string | readonly string[];
16
- }
17
-
18
- export class CrdtManager<TCrdt extends AbstractCrdtDocFactory<any, any>> {
19
- public doc: InferDocLike<TCrdt>;
20
- public initialized: boolean = false;
21
-
22
- private readonly _docFactory: TCrdt;
23
-
24
- constructor(options: CrdtManagerOptions<TCrdt>) {
25
- const { initialStorage = noop.doc({}) as any } = options;
26
-
27
- this._docFactory = initialStorage;
28
- this.doc = this._docFactory.getEmpty() as InferDocLike<TCrdt>;
29
- }
30
-
31
- /**
32
- * !HACK
33
- * @description If this is called before the doc is initialized. Omit the
34
- * update. This unfortunately means updates can be dropped entirely
35
- * @date June 13, 2023
36
- */
37
- public applyUpdate(params: ApplyUpdateParams): this {
38
- const { origin, update } = params;
39
-
40
- if (!this.initialized) return this;
41
-
42
- const updates: readonly string[] = typeof update === "string" ? [update] : update;
43
-
44
- this._applyDocUpdates(this.doc, updates, origin);
45
-
46
- return this;
47
- }
48
-
49
- public destroy(): void {
50
- this.initialized = false;
51
- this.doc.destroy();
52
- this.doc = this._docFactory.getEmpty() as InferDocLike<TCrdt>;
53
- }
54
-
55
- public get<TKey extends keyof InferStorage<TCrdt>>(key: TKey): InferStorage<TCrdt>[TKey] {
56
- return this.doc.get(key);
57
- }
58
-
59
- public getInitialState(): string {
60
- return this._docFactory.getInitialized().getEncodedState();
61
- }
62
-
63
- public initialize(params: CrdtManagerInitializeParams): this {
64
- const { origin, update } = params;
65
-
66
- /**
67
- * !HACK
68
- * @description If the doc was already initialized, we don't want to re-initialize
69
- * the doc and overwrite what's already there. Skip the initialization and log a
70
- * warning.
71
- * @date May 7, 2025
72
- */
73
- if (this.initialized) {
74
- console.warn("Attempted to initialize storage multiple times");
75
- return this;
76
- }
77
-
78
- /**
79
- * !HACK
80
- * @description If the doc is already populated, somehow we're attempting to overwrite
81
- * a doc that was presumably initialized but not identified as initialized. Skip the
82
- * initialization and log a warning.
83
- * @date May 7, 2025
84
- */
85
- if (!this.doc.isEmpty()) {
86
- console.warn("Attempted to initialize over a non-empty storage");
87
- return this;
88
- }
89
-
90
- const updates = typeof update === "string" ? [update] : update;
91
-
92
- if (!updates.length) return this;
93
-
94
- const initialized = this._docFactory.getInitialized();
95
- const reference = initialized.get();
96
-
97
- this.doc = this._applyDocUpdates(this.doc, updates, origin).rebuildStorage(reference);
98
- this.initialized = true;
99
- initialized.destroy();
100
-
101
- return this;
102
- }
103
-
104
- public resolveEncodedState(updates: string | string[] | readonly string[]): string | null {
105
- return this._docFactory.resolveEncodedState(updates);
106
- }
107
-
108
- private _applyDocUpdates(
109
- doc: InferDocLike<TCrdt>,
110
- updates: readonly string[],
111
- origin?: string,
112
- ): InferDocLike<TCrdt> {
113
- doc.transact(() => {
114
- doc.batchApplyEncodedState({ origin, updates });
115
- }, origin);
116
-
117
- return doc;
118
- }
119
- }
@@ -1,46 +0,0 @@
1
- import type { CrdtType, InferCrdtJson } from "@pluv/crdt";
2
- import type { StorageSubscriptionCallback } from "@pluv/types";
3
- import type { Subject } from "wonka";
4
- import { makeSubject, subscribe } from "wonka";
5
-
6
- export class CrdtNotifier<TStorage extends Record<string, CrdtType<any, any>>> {
7
- public rootSubject = makeSubject<{
8
- [P in keyof TStorage]: InferCrdtJson<TStorage[P]>;
9
- }>();
10
-
11
- public subjects = new Map<
12
- keyof TStorage,
13
- Subject<InferCrdtJson<TStorage[keyof TStorage]>> | null
14
- >();
15
-
16
- public subject<TKey extends keyof TStorage>(key: TKey): Subject<InferCrdtJson<TStorage[TKey]>> {
17
- const subject = this.subjects.get(key);
18
-
19
- if (subject) {
20
- return subject as Subject<InferCrdtJson<TStorage[TKey]>>;
21
- }
22
-
23
- const newSubject = makeSubject<InferCrdtJson<TStorage[TKey]>>();
24
-
25
- this.subjects.set(key, newSubject);
26
-
27
- return newSubject as Subject<InferCrdtJson<TStorage[TKey]>>;
28
- }
29
-
30
- public subcribeRoot(
31
- callback: (value: {
32
- [P in keyof TStorage]: InferCrdtJson<TStorage[P]>;
33
- }) => void,
34
- ): () => void {
35
- return subscribe(callback)(this.rootSubject.source).unsubscribe;
36
- }
37
-
38
- public subscribe<TKey extends keyof TStorage>(
39
- key: TKey,
40
- callback: StorageSubscriptionCallback<TStorage, TKey>,
41
- ): () => void {
42
- const subject = this.subject(key);
43
-
44
- return subscribe(callback)(subject.source).unsubscribe;
45
- }
46
- }
@@ -1,39 +0,0 @@
1
- import type {
2
- EventNotifierSubscriptionCallback,
3
- Id,
4
- InferIOOutput,
5
- IOEventMessage,
6
- IOLike,
7
- } from "@pluv/types";
8
- import type { Subject } from "wonka";
9
- import { makeSubject, subscribe } from "wonka";
10
-
11
- export class EventNotifier<TIO extends IOLike> {
12
- public subjects = new Map<
13
- keyof InferIOOutput<TIO>,
14
- Subject<Id<IOEventMessage<TIO, keyof InferIOOutput<TIO>>>>
15
- >();
16
-
17
- public subject<TEvent extends keyof InferIOOutput<TIO>>(
18
- name: TEvent,
19
- ): Subject<Id<IOEventMessage<TIO, TEvent>>> {
20
- const subject = this.subjects.get(name);
21
-
22
- if (subject) return subject;
23
-
24
- const newSubject = makeSubject<Id<IOEventMessage<TIO, TEvent>>>();
25
-
26
- this.subjects.set(name, newSubject);
27
-
28
- return newSubject;
29
- }
30
-
31
- public subscribe<TEvent extends keyof InferIOOutput<TIO>>(
32
- name: TEvent,
33
- callback: EventNotifierSubscriptionCallback<TIO, TEvent>,
34
- ): () => void {
35
- const subject = this.subject(name);
36
-
37
- return subscribe(callback)(subject.source).unsubscribe;
38
- }
39
- }
@@ -1,21 +0,0 @@
1
- import { makeSubject, subscribe, TypeOfSource } from "wonka";
2
-
3
- export class ListenerManager {
4
- public subjects = {
5
- close: makeSubject<CloseEvent>(),
6
- error: makeSubject<Event>(),
7
- message: makeSubject<MessageEvent<any>>(),
8
- open: makeSubject<Event>(),
9
- };
10
-
11
- public subscribe<TKind extends keyof typeof this.subjects>(
12
- kind: TKind,
13
- callback: (event: TypeOfSource<(typeof this.subjects)[TKind]["source"]>) => void,
14
- ): () => void {
15
- const source = this.subjects[kind]?.source;
16
-
17
- if (!source) return () => undefined;
18
-
19
- return subscribe(callback)(source as any).unsubscribe;
20
- }
21
- }