@abraca/dabra 0.1.0 → 0.1.2

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.
@@ -1,4 +1,4 @@
1
- import { readAuthMessage } from "@hocuspocus/common";
1
+ import { readAuthMessage } from "@abraca/dabra-common";
2
2
  import { readVarInt, readVarString } from "lib0/decoding";
3
3
  import type { CloseEvent } from "ws";
4
4
  import * as awarenessProtocol from "y-protocols/awareness";
@@ -9,131 +9,128 @@ import { OutgoingMessage } from "./OutgoingMessage.ts";
9
9
  import { MessageType } from "./types.ts";
10
10
 
11
11
  export class MessageReceiver {
12
- message: IncomingMessage;
13
-
14
- constructor(message: IncomingMessage) {
15
- this.message = message;
16
- }
17
-
18
- public apply(provider: HocuspocusProvider, emitSynced: boolean) {
19
- const { message } = this;
20
- const type = message.readVarUint();
21
-
22
- const emptyMessageLength = message.length();
23
-
24
- switch (type) {
25
- case MessageType.Sync:
26
- this.applySyncMessage(provider, emitSynced);
27
- break;
28
-
29
- case MessageType.Awareness:
30
- this.applyAwarenessMessage(provider);
31
- break;
32
-
33
- case MessageType.Auth:
34
- this.applyAuthMessage(provider);
35
- break;
36
-
37
- case MessageType.QueryAwareness:
38
- this.applyQueryAwarenessMessage(provider);
39
- break;
40
-
41
- case MessageType.Stateless:
42
- provider.receiveStateless(readVarString(message.decoder));
43
- break;
44
-
45
- case MessageType.SyncStatus:
46
- this.applySyncStatusMessage(
47
- provider,
48
- readVarInt(message.decoder) === 1,
49
- );
50
- break;
51
-
52
- case MessageType.CLOSE:
53
- // eslint-disable-next-line no-case-declarations
54
- const event: CloseEvent = {
55
- code: 1000,
56
- reason: readVarString(message.decoder),
57
- // @ts-ignore
58
- target: provider.configuration.websocketProvider.webSocket!,
59
- type: "close",
60
- };
61
- provider.onClose();
62
- provider.configuration.onClose({ event });
63
- provider.forwardClose({ event });
64
- break;
65
-
66
- default:
67
- throw new Error(`Can’t apply message of unknown type: ${type}`);
68
- }
69
-
70
- // Reply
71
- if (message.length() > emptyMessageLength + 1) {
72
- // length of documentName (considered in emptyMessageLength plus length of yjs sync type, set in applySyncMessage)
73
- // @ts-ignore
74
- provider.send(OutgoingMessage, { encoder: message.encoder });
75
- }
76
- }
77
-
78
- private applySyncMessage(provider: HocuspocusProvider, emitSynced: boolean) {
79
- const { message } = this;
80
-
81
- message.writeVarUint(MessageType.Sync);
82
-
83
- // Apply update
84
- const syncMessageType = readSyncMessage(
85
- message.decoder,
86
- message.encoder,
87
- provider.document,
88
- provider,
89
- );
90
-
91
- // Synced once we receive Step2
92
- if (emitSynced && syncMessageType === messageYjsSyncStep2) {
93
- provider.synced = true;
94
- }
95
- }
96
-
97
- applySyncStatusMessage(provider: HocuspocusProvider, applied: boolean) {
98
- if (applied) {
99
- provider.decrementUnsyncedChanges();
100
- }
101
- }
102
-
103
- private applyAwarenessMessage(provider: HocuspocusProvider) {
104
- if (!provider.awareness) return;
105
-
106
- const { message } = this;
107
-
108
- awarenessProtocol.applyAwarenessUpdate(
109
- provider.awareness,
110
- message.readVarUint8Array(),
111
- provider,
112
- );
113
- }
114
-
115
- private applyAuthMessage(provider: HocuspocusProvider) {
116
- const { message } = this;
117
-
118
- readAuthMessage(
119
- message.decoder,
120
- provider.sendToken.bind(provider),
121
- provider.permissionDeniedHandler.bind(provider),
122
- provider.authenticatedHandler.bind(provider),
123
- );
124
- }
125
-
126
- private applyQueryAwarenessMessage(provider: HocuspocusProvider) {
127
- if (!provider.awareness) return;
128
-
129
- const { message } = this;
130
-
131
- message.writeVarUint(MessageType.Awareness);
132
- message.writeVarUint8Array(
133
- awarenessProtocol.encodeAwarenessUpdate(
134
- provider.awareness,
135
- Array.from(provider.awareness.getStates().keys()),
136
- ),
137
- );
138
- }
12
+ message: IncomingMessage;
13
+
14
+ constructor(message: IncomingMessage) {
15
+ this.message = message;
16
+ }
17
+
18
+ public apply(provider: HocuspocusProvider, emitSynced: boolean) {
19
+ const { message } = this;
20
+ const type = message.readVarUint();
21
+
22
+ const emptyMessageLength = message.length();
23
+
24
+ switch (type) {
25
+ case MessageType.Sync:
26
+ this.applySyncMessage(provider, emitSynced);
27
+ break;
28
+
29
+ case MessageType.Awareness:
30
+ this.applyAwarenessMessage(provider);
31
+ break;
32
+
33
+ case MessageType.Auth:
34
+ this.applyAuthMessage(provider);
35
+ break;
36
+
37
+ case MessageType.QueryAwareness:
38
+ this.applyQueryAwarenessMessage(provider);
39
+ break;
40
+
41
+ case MessageType.Stateless:
42
+ provider.receiveStateless(readVarString(message.decoder));
43
+ break;
44
+
45
+ case MessageType.SyncStatus:
46
+ this.applySyncStatusMessage(provider, readVarInt(message.decoder) === 1);
47
+ break;
48
+
49
+ case MessageType.CLOSE:
50
+ // eslint-disable-next-line no-case-declarations
51
+ const event: CloseEvent = {
52
+ code: 1000,
53
+ reason: readVarString(message.decoder),
54
+ // @ts-ignore
55
+ target: provider.configuration.websocketProvider.webSocket!,
56
+ type: "close",
57
+ };
58
+ provider.onClose();
59
+ provider.configuration.onClose({ event });
60
+ provider.forwardClose({ event });
61
+ break;
62
+
63
+ default:
64
+ throw new Error(`Can’t apply message of unknown type: ${type}`);
65
+ }
66
+
67
+ // Reply
68
+ if (message.length() > emptyMessageLength + 1) {
69
+ // length of documentName (considered in emptyMessageLength plus length of yjs sync type, set in applySyncMessage)
70
+ // @ts-ignore
71
+ provider.send(OutgoingMessage, { encoder: message.encoder });
72
+ }
73
+ }
74
+
75
+ private applySyncMessage(provider: HocuspocusProvider, emitSynced: boolean) {
76
+ const { message } = this;
77
+
78
+ message.writeVarUint(MessageType.Sync);
79
+
80
+ // Apply update
81
+ const syncMessageType = readSyncMessage(
82
+ message.decoder,
83
+ message.encoder,
84
+ provider.document,
85
+ provider,
86
+ );
87
+
88
+ // Synced once we receive Step2
89
+ if (emitSynced && syncMessageType === messageYjsSyncStep2) {
90
+ provider.synced = true;
91
+ }
92
+ }
93
+
94
+ applySyncStatusMessage(provider: HocuspocusProvider, applied: boolean) {
95
+ if (applied) {
96
+ provider.decrementUnsyncedChanges();
97
+ }
98
+ }
99
+
100
+ private applyAwarenessMessage(provider: HocuspocusProvider) {
101
+ if (!provider.awareness) return;
102
+
103
+ const { message } = this;
104
+
105
+ awarenessProtocol.applyAwarenessUpdate(
106
+ provider.awareness,
107
+ message.readVarUint8Array(),
108
+ provider,
109
+ );
110
+ }
111
+
112
+ private applyAuthMessage(provider: HocuspocusProvider) {
113
+ const { message } = this;
114
+
115
+ readAuthMessage(
116
+ message.decoder,
117
+ provider.sendToken.bind(provider),
118
+ provider.permissionDeniedHandler.bind(provider),
119
+ provider.authenticatedHandler.bind(provider),
120
+ );
121
+ }
122
+
123
+ private applyQueryAwarenessMessage(provider: HocuspocusProvider) {
124
+ if (!provider.awareness) return;
125
+
126
+ const { message } = this;
127
+
128
+ message.writeVarUint(MessageType.Awareness);
129
+ message.writeVarUint8Array(
130
+ awarenessProtocol.encodeAwarenessUpdate(
131
+ provider.awareness,
132
+ Array.from(provider.awareness.getStates().keys()),
133
+ ),
134
+ );
135
+ }
139
136
  }
@@ -1,25 +1,23 @@
1
1
  import { writeVarString, writeVarUint } from "lib0/encoding";
2
- import { writeAuthentication } from "@hocuspocus/common";
2
+ import { writeAuthentication } from "@abraca/dabra-common";
3
3
  import type { OutgoingMessageArguments } from "../types.ts";
4
4
  import { MessageType } from "../types.ts";
5
5
  import { OutgoingMessage } from "../OutgoingMessage.ts";
6
6
 
7
7
  export class AuthenticationMessage extends OutgoingMessage {
8
- type = MessageType.Auth;
8
+ type = MessageType.Auth;
9
9
 
10
- description = "Authentication";
10
+ description = "Authentication";
11
11
 
12
- get(args: Partial<OutgoingMessageArguments>) {
13
- if (typeof args.token === "undefined") {
14
- throw new Error(
15
- "The authentication message requires `token` as an argument.",
16
- );
17
- }
12
+ get(args: Partial<OutgoingMessageArguments>) {
13
+ if (typeof args.token === "undefined") {
14
+ throw new Error("The authentication message requires `token` as an argument.");
15
+ }
18
16
 
19
- writeVarString(this.encoder, args.documentName!);
20
- writeVarUint(this.encoder, this.type);
21
- writeAuthentication(this.encoder, args.token);
17
+ writeVarString(this.encoder, args.documentName!);
18
+ writeVarUint(this.encoder, this.type);
19
+ writeAuthentication(this.encoder, args.token);
22
20
 
23
- return this.encoder;
24
- }
21
+ return this.encoder;
22
+ }
25
23
  }
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ export * from "./HocuspocusProvider.ts";
2
2
  export * from "./HocuspocusProviderWebsocket.ts";
3
3
  export * from "./types.ts";
4
4
  export * from "./AbracadabraProvider.ts";
5
+ export * from "./AbracadabraClient.ts";
5
6
  export * from "./OfflineStore.ts";
6
7
  export { SubdocMessage } from "./OutgoingMessages/SubdocMessage.ts";
7
8
  export { CryptoIdentityKeystore } from "./CryptoIdentityKeystore.ts";
package/src/types.ts CHANGED
@@ -2,7 +2,7 @@ import type { Encoder } from "lib0/encoding";
2
2
  import type { Event, MessageEvent } from "ws";
3
3
  import type { Awareness } from "y-protocols/awareness";
4
4
  import type * as Y from "yjs";
5
- import type { CloseEvent } from "@hocuspocus/common";
5
+ import type { CloseEvent } from "@abraca/dabra-common";
6
6
  import type { IncomingMessage } from "./IncomingMessage.ts";
7
7
  import type { OutgoingMessage } from "./OutgoingMessage.ts";
8
8
  import type { AuthenticationMessage } from "./OutgoingMessages/AuthenticationMessage.ts";
@@ -13,104 +13,104 @@ import type { SyncStepTwoMessage } from "./OutgoingMessages/SyncStepTwoMessage.t
13
13
  import type { UpdateMessage } from "./OutgoingMessages/UpdateMessage.ts";
14
14
 
15
15
  export enum MessageType {
16
- Sync = 0,
17
- Awareness = 1,
18
- Auth = 2,
19
- QueryAwareness = 3,
20
- Subdoc = 4,
21
- Stateless = 5,
22
- CLOSE = 7,
23
- SyncStatus = 8,
16
+ Sync = 0,
17
+ Awareness = 1,
18
+ Auth = 2,
19
+ QueryAwareness = 3,
20
+ Subdoc = 4,
21
+ Stateless = 5,
22
+ CLOSE = 7,
23
+ SyncStatus = 8,
24
24
  }
25
25
 
26
26
  export enum WebSocketStatus {
27
- Connecting = "connecting",
28
- Connected = "connected",
29
- Disconnected = "disconnected",
27
+ Connecting = "connecting",
28
+ Connected = "connected",
29
+ Disconnected = "disconnected",
30
30
  }
31
31
 
32
32
  export type AuthorizedScope = "read-write" | "readonly";
33
33
 
34
34
  export interface OutgoingMessageInterface {
35
- encoder: Encoder;
36
- type?: MessageType;
35
+ encoder: Encoder;
36
+ type?: MessageType;
37
37
  }
38
38
 
39
39
  export interface OutgoingMessageArguments {
40
- documentName: string;
41
- token: string;
42
- document: Y.Doc;
43
- awareness: Awareness;
44
- clients: number[];
45
- states: Map<number, { [key: string]: any }>;
46
- update: any;
47
- payload: string;
48
- encoder: Encoder;
40
+ documentName: string;
41
+ token: string;
42
+ document: Y.Doc;
43
+ awareness: Awareness;
44
+ clients: number[];
45
+ states: Map<number, { [key: string]: any }>;
46
+ update: any;
47
+ payload: string;
48
+ encoder: Encoder;
49
49
  }
50
50
 
51
51
  export interface Constructable<T> {
52
- new (...args: any): T;
52
+ new (...args: any): T;
53
53
  }
54
54
 
55
55
  export type ConstructableOutgoingMessage =
56
- | Constructable<AuthenticationMessage>
57
- | Constructable<AwarenessMessage>
58
- | Constructable<QueryAwarenessMessage>
59
- | Constructable<SyncStepOneMessage>
60
- | Constructable<SyncStepTwoMessage>
61
- | Constructable<UpdateMessage>;
56
+ | Constructable<AuthenticationMessage>
57
+ | Constructable<AwarenessMessage>
58
+ | Constructable<QueryAwarenessMessage>
59
+ | Constructable<SyncStepOneMessage>
60
+ | Constructable<SyncStepTwoMessage>
61
+ | Constructable<UpdateMessage>;
62
62
 
63
63
  export type onAuthenticationFailedParameters = {
64
- reason: string;
64
+ reason: string;
65
65
  };
66
66
 
67
67
  export type onAuthenticatedParameters = {
68
- scope: AuthorizedScope;
68
+ scope: AuthorizedScope;
69
69
  };
70
70
 
71
71
  export type onOpenParameters = {
72
- event: Event;
72
+ event: Event;
73
73
  };
74
74
 
75
75
  export type onMessageParameters = {
76
- event: MessageEvent;
77
- message: IncomingMessage;
76
+ event: MessageEvent;
77
+ message: IncomingMessage;
78
78
  };
79
79
 
80
80
  export type onOutgoingMessageParameters = {
81
- message: OutgoingMessage;
81
+ message: OutgoingMessage;
82
82
  };
83
83
 
84
84
  export type onStatusParameters = {
85
- status: WebSocketStatus;
85
+ status: WebSocketStatus;
86
86
  };
87
87
 
88
88
  export type onSyncedParameters = {
89
- state: boolean;
89
+ state: boolean;
90
90
  };
91
91
 
92
92
  export type onUnsyncedChangesParameters = {
93
- number: number;
93
+ number: number;
94
94
  };
95
95
 
96
96
  export type onDisconnectParameters = {
97
- event: CloseEvent;
97
+ event: CloseEvent;
98
98
  };
99
99
 
100
100
  export type onCloseParameters = {
101
- event: CloseEvent;
101
+ event: CloseEvent;
102
102
  };
103
103
 
104
104
  export type onAwarenessUpdateParameters = {
105
- states: StatesArray;
105
+ states: StatesArray;
106
106
  };
107
107
 
108
108
  export type onAwarenessChangeParameters = {
109
- states: StatesArray;
109
+ states: StatesArray;
110
110
  };
111
111
 
112
112
  export type onStatelessParameters = {
113
- payload: string;
113
+ payload: string;
114
114
  };
115
115
 
116
116
  export type StatesArray = { clientId: number; [key: string | number]: any }[];
@@ -119,26 +119,70 @@ export type StatesArray = { clientId: number; [key: string | number]: any }[];
119
119
 
120
120
  export type EffectiveRole = "owner" | "editor" | "viewer" | null;
121
121
 
122
- /** Ed25519 identity for passwordless crypto auth (Model B multi-key). */
122
+ /**
123
+ * Ed25519 identity for passwordless crypto auth.
124
+ *
125
+ * The public key is the sole identifier sent to the server during the
126
+ * challenge-response handshake. Username is decoupled from auth and is
127
+ * managed separately as a mutable display name (see PATCH /users/me).
128
+ */
123
129
  export interface CryptoIdentity {
124
- username: string;
125
- /** base64url-encoded Ed25519 public key (32 bytes) */
126
- publicKey: string;
130
+ /** base64url-encoded Ed25519 public key (32 bytes). Primary auth identifier. */
131
+ publicKey: string;
127
132
  }
128
133
 
129
134
  export interface SubdocRegisteredEvent {
130
- childId: string;
131
- parentId: string;
135
+ childId: string;
136
+ parentId: string;
132
137
  }
133
138
 
134
139
  export type onSubdocRegisteredParameters = SubdocRegisteredEvent;
135
140
 
136
141
  export type onSubdocLoadedParameters = {
137
- childId: string;
138
- provider: import("./AbracadabraProvider.ts").AbracadabraProvider;
142
+ childId: string;
143
+ provider: import("./AbracadabraProvider.ts").AbracadabraProvider;
139
144
  };
140
145
 
141
- export interface AbracadabraOutgoingMessageArguments
142
- extends OutgoingMessageArguments {
143
- childDocumentName: string;
146
+ export interface AbracadabraOutgoingMessageArguments extends OutgoingMessageArguments {
147
+ childDocumentName: string;
148
+ }
149
+
150
+ // ── REST API response types ──────────────────────────────────────────────────
151
+
152
+ export interface UserProfile {
153
+ id: string;
154
+ username: string;
155
+ email: string | null;
156
+ displayName: string | null;
157
+ }
158
+
159
+ export interface DocumentMeta {
160
+ id: string;
161
+ parent_id: string | null;
162
+ }
163
+
164
+ export interface UploadMeta {
165
+ id: string;
166
+ doc_id: string;
167
+ filename: string;
168
+ }
169
+
170
+ export interface UploadInfo {
171
+ id: string;
172
+ filename: string;
173
+ mime_type: string;
174
+ size: number;
175
+ }
176
+
177
+ export interface PublicKeyInfo {
178
+ id: string;
179
+ publicKey: string;
180
+ deviceName: string | null;
181
+ revoked: boolean;
182
+ }
183
+
184
+ export interface HealthStatus {
185
+ status: string;
186
+ version: string;
187
+ active_documents: number;
144
188
  }