@meshagent/meshagent 0.37.1 → 0.38.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/CHANGELOG.md +6 -0
- package/dist/browser/agent.js +74 -10
- package/dist/browser/developer-client.js +3 -0
- package/dist/browser/helpers.d.ts +2 -2
- package/dist/browser/helpers.js +1 -1
- package/dist/browser/meshagent-client.d.ts +25 -0
- package/dist/browser/meshagent-client.js +65 -0
- package/dist/browser/messaging-client.d.ts +29 -16
- package/dist/browser/messaging-client.js +256 -154
- package/dist/browser/participant.d.ts +7 -2
- package/dist/browser/participant.js +9 -9
- package/dist/browser/protocol.d.ts +85 -28
- package/dist/browser/protocol.js +356 -119
- package/dist/browser/room-client.d.ts +165 -29
- package/dist/browser/room-client.js +1114 -74
- package/dist/browser/room-event.d.ts +11 -0
- package/dist/browser/room-event.js +21 -1
- package/dist/browser/room-server-client.d.ts +2 -0
- package/dist/browser/room-server-client.js +6 -0
- package/dist/browser/runtime.d.ts +1 -1
- package/dist/browser/runtime.js +3 -1
- package/dist/browser/secrets-client.js +6 -2
- package/dist/browser/storage-client.d.ts +1 -0
- package/dist/browser/storage-client.js +9 -0
- package/dist/browser/sync-client.d.ts +16 -14
- package/dist/browser/sync-client.js +195 -116
- package/dist/esm/agent.js +74 -10
- package/dist/esm/developer-client.js +3 -0
- package/dist/esm/helpers.d.ts +2 -2
- package/dist/esm/helpers.js +1 -1
- package/dist/esm/meshagent-client.d.ts +25 -0
- package/dist/esm/meshagent-client.js +65 -0
- package/dist/esm/messaging-client.d.ts +29 -16
- package/dist/esm/messaging-client.js +256 -154
- package/dist/esm/participant.d.ts +7 -2
- package/dist/esm/participant.js +9 -9
- package/dist/esm/protocol.d.ts +85 -28
- package/dist/esm/protocol.js +352 -118
- package/dist/esm/room-client.d.ts +165 -29
- package/dist/esm/room-client.js +1112 -73
- package/dist/esm/room-event.d.ts +11 -0
- package/dist/esm/room-event.js +19 -0
- package/dist/esm/room-server-client.d.ts +2 -0
- package/dist/esm/room-server-client.js +7 -1
- package/dist/esm/runtime.d.ts +1 -1
- package/dist/esm/runtime.js +1 -1
- package/dist/esm/secrets-client.js +6 -2
- package/dist/esm/storage-client.d.ts +1 -0
- package/dist/esm/storage-client.js +9 -0
- package/dist/esm/sync-client.d.ts +16 -14
- package/dist/esm/sync-client.js +196 -117
- package/dist/node/agent.js +74 -10
- package/dist/node/developer-client.js +3 -0
- package/dist/node/helpers.d.ts +2 -2
- package/dist/node/helpers.js +1 -1
- package/dist/node/meshagent-client.d.ts +25 -0
- package/dist/node/meshagent-client.js +65 -0
- package/dist/node/messaging-client.d.ts +29 -16
- package/dist/node/messaging-client.js +256 -154
- package/dist/node/participant.d.ts +7 -2
- package/dist/node/participant.js +9 -9
- package/dist/node/protocol.d.ts +85 -28
- package/dist/node/protocol.js +356 -119
- package/dist/node/room-client.d.ts +165 -29
- package/dist/node/room-client.js +1114 -74
- package/dist/node/room-event.d.ts +11 -0
- package/dist/node/room-event.js +21 -1
- package/dist/node/room-server-client.d.ts +2 -0
- package/dist/node/room-server-client.js +6 -0
- package/dist/node/runtime.d.ts +1 -1
- package/dist/node/runtime.js +3 -1
- package/dist/node/secrets-client.js +6 -2
- package/dist/node/storage-client.d.ts +1 -0
- package/dist/node/storage-client.js +9 -0
- package/dist/node/sync-client.d.ts +16 -14
- package/dist/node/sync-client.js +195 -116
- package/package.json +6 -3
|
@@ -2,6 +2,17 @@ export declare abstract class RoomEvent {
|
|
|
2
2
|
abstract get name(): string;
|
|
3
3
|
abstract get description(): string;
|
|
4
4
|
}
|
|
5
|
+
export declare class RoomStatusEvent extends RoomEvent {
|
|
6
|
+
readonly status: string;
|
|
7
|
+
readonly message: string;
|
|
8
|
+
constructor({ status, message }: {
|
|
9
|
+
status: string;
|
|
10
|
+
message: string;
|
|
11
|
+
});
|
|
12
|
+
get name(): string;
|
|
13
|
+
get description(): string;
|
|
14
|
+
static fromJson(json: Record<string, unknown>): RoomStatusEvent;
|
|
15
|
+
}
|
|
5
16
|
export declare class RoomMessage {
|
|
6
17
|
fromParticipantId: string;
|
|
7
18
|
type: string;
|
package/dist/node/room-event.js
CHANGED
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RoomLogEvent = exports.FileMovedEvent = exports.FileUpdatedEvent = exports.FileDeletedEvent = exports.FileCreatedEvent = exports.RoomMessageEvent = exports.RoomMessage = exports.RoomEvent = void 0;
|
|
3
|
+
exports.RoomLogEvent = exports.FileMovedEvent = exports.FileUpdatedEvent = exports.FileDeletedEvent = exports.FileCreatedEvent = exports.RoomMessageEvent = exports.RoomMessage = exports.RoomStatusEvent = exports.RoomEvent = void 0;
|
|
4
4
|
class RoomEvent {
|
|
5
5
|
}
|
|
6
6
|
exports.RoomEvent = RoomEvent;
|
|
7
|
+
class RoomStatusEvent extends RoomEvent {
|
|
8
|
+
constructor({ status, message }) {
|
|
9
|
+
super();
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.message = message;
|
|
12
|
+
}
|
|
13
|
+
get name() {
|
|
14
|
+
return this.status;
|
|
15
|
+
}
|
|
16
|
+
get description() {
|
|
17
|
+
return this.message;
|
|
18
|
+
}
|
|
19
|
+
static fromJson(json) {
|
|
20
|
+
return new RoomStatusEvent({
|
|
21
|
+
status: String(json["status"]),
|
|
22
|
+
message: String(json["message"]),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.RoomStatusEvent = RoomStatusEvent;
|
|
7
27
|
class RoomMessage {
|
|
8
28
|
constructor({ fromParticipantId, type, message, local = false, attachment }) {
|
|
9
29
|
this.fromParticipantId = fromParticipantId;
|
|
@@ -13,6 +13,8 @@ export declare class MeshDocument extends RuntimeDocument {
|
|
|
13
13
|
});
|
|
14
14
|
onSendUpdateToBackend: (base64: string) => void;
|
|
15
15
|
onSendUpdateToClient: (base64: string) => void;
|
|
16
|
+
getState(vector?: string): string;
|
|
17
|
+
getStateVector(): string;
|
|
16
18
|
get synchronized(): Promise<boolean>;
|
|
17
19
|
get isSynchronized(): boolean;
|
|
18
20
|
setSynchronizedComplete(): void;
|
|
@@ -34,6 +34,12 @@ class MeshDocument extends document_1.RuntimeDocument {
|
|
|
34
34
|
};
|
|
35
35
|
(0, runtime_1.registerDocument)(this.id, null, false, this.onSendUpdateToBackend, this.onSendUpdateToClient);
|
|
36
36
|
}
|
|
37
|
+
getState(vector) {
|
|
38
|
+
return (0, runtime_1.getState)(this.id, vector ?? null);
|
|
39
|
+
}
|
|
40
|
+
getStateVector() {
|
|
41
|
+
return (0, runtime_1.getStateVector)(this.id);
|
|
42
|
+
}
|
|
37
43
|
get synchronized() {
|
|
38
44
|
return this._synchronized.fut;
|
|
39
45
|
}
|
package/dist/node/runtime.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { applyBackendChanges, applyChanges, registerDocument, unregisterDocument, } from './entrypoint.js';
|
|
1
|
+
export { applyBackendChanges, applyChanges, getState, getStateVector, registerDocument, unregisterDocument, } from './entrypoint.js';
|
|
2
2
|
export type SendUpdateFn = (msg: string) => void;
|
|
3
3
|
export interface UpdatePayload {
|
|
4
4
|
documentID: string;
|
package/dist/node/runtime.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.unregisterDocument = exports.registerDocument = exports.applyChanges = exports.applyBackendChanges = void 0;
|
|
3
|
+
exports.unregisterDocument = exports.registerDocument = exports.getStateVector = exports.getState = exports.applyChanges = exports.applyBackendChanges = void 0;
|
|
4
4
|
var entrypoint_js_1 = require("./entrypoint.js");
|
|
5
5
|
Object.defineProperty(exports, "applyBackendChanges", { enumerable: true, get: function () { return entrypoint_js_1.applyBackendChanges; } });
|
|
6
6
|
Object.defineProperty(exports, "applyChanges", { enumerable: true, get: function () { return entrypoint_js_1.applyChanges; } });
|
|
7
|
+
Object.defineProperty(exports, "getState", { enumerable: true, get: function () { return entrypoint_js_1.getState; } });
|
|
8
|
+
Object.defineProperty(exports, "getStateVector", { enumerable: true, get: function () { return entrypoint_js_1.getStateVector; } });
|
|
7
9
|
Object.defineProperty(exports, "registerDocument", { enumerable: true, get: function () { return entrypoint_js_1.registerDocument; } });
|
|
8
10
|
Object.defineProperty(exports, "unregisterDocument", { enumerable: true, get: function () { return entrypoint_js_1.unregisterDocument; } });
|
|
@@ -76,7 +76,9 @@ class SecretsClient {
|
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
78
|
async _handleClientOAuthTokenRequest(protocol, messageId, type, bytes) {
|
|
79
|
-
|
|
79
|
+
if (!this.client.isActiveProtocol(protocol)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
80
82
|
void messageId;
|
|
81
83
|
void type;
|
|
82
84
|
if (bytes == null) {
|
|
@@ -112,7 +114,9 @@ class SecretsClient {
|
|
|
112
114
|
});
|
|
113
115
|
}
|
|
114
116
|
async _handleClientSecretRequest(protocol, messageId, type, bytes) {
|
|
115
|
-
|
|
117
|
+
if (!this.client.isActiveProtocol(protocol)) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
116
120
|
void messageId;
|
|
117
121
|
void type;
|
|
118
122
|
if (bytes == null) {
|
|
@@ -4,6 +4,7 @@ import { RoomEvent } from "./room-event";
|
|
|
4
4
|
import { BinaryContent, FileContent } from "./response";
|
|
5
5
|
import { EventEmitter } from "./event-emitter";
|
|
6
6
|
type StorageClientRoom = Pick<RoomClient, "invoke" | "invokeStream" | "emit"> & {
|
|
7
|
+
isActiveProtocol(protocol: Protocol): boolean;
|
|
7
8
|
protocol: Pick<Protocol, "addHandler">;
|
|
8
9
|
};
|
|
9
10
|
export declare class FileHandle {
|
|
@@ -89,18 +89,27 @@ class StorageClient extends event_emitter_1.EventEmitter {
|
|
|
89
89
|
this.client.protocol.addHandler("storage.file.updated", this._handleFileUpdated.bind(this));
|
|
90
90
|
}
|
|
91
91
|
async _handleFileUpdated(protocol, messageId, type, bytes) {
|
|
92
|
+
if (!this.client.isActiveProtocol(protocol)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
92
95
|
const [data, _] = (0, utils_1.unpackMessage)(bytes || new Uint8Array());
|
|
93
96
|
const event = new room_event_1.FileUpdatedEvent({ path: data["path"], participantId: data["participant_id"] });
|
|
94
97
|
this.client.emit(event);
|
|
95
98
|
this.emit('file.updated', event);
|
|
96
99
|
}
|
|
97
100
|
async _handleFileDeleted(protocol, messageId, type, bytes) {
|
|
101
|
+
if (!this.client.isActiveProtocol(protocol)) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
98
104
|
const [data, _] = (0, utils_1.unpackMessage)(bytes || new Uint8Array());
|
|
99
105
|
const event = new room_event_1.FileDeletedEvent({ path: data["path"], participantId: data["participant_id"] });
|
|
100
106
|
this.client.emit(event);
|
|
101
107
|
this.emit('file.deleted', event);
|
|
102
108
|
}
|
|
103
109
|
async _handleFileMoved(protocol, messageId, type, bytes) {
|
|
110
|
+
if (!this.client.isActiveProtocol(protocol)) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
104
113
|
const [data, _] = (0, utils_1.unpackMessage)(bytes || new Uint8Array());
|
|
105
114
|
const event = new room_event_1.FileMovedEvent({
|
|
106
115
|
sourcePath: data["source_path"],
|
|
@@ -1,36 +1,38 @@
|
|
|
1
1
|
import { EventEmitter } from "./event-emitter";
|
|
2
|
-
import { RoomClient } from "./room-client";
|
|
3
2
|
import { MeshSchema } from "./schema";
|
|
3
|
+
import { RoomClient } from "./room-client";
|
|
4
4
|
import { MeshDocument } from "./room-server-client";
|
|
5
5
|
export interface SyncClientEvent {
|
|
6
6
|
type: string;
|
|
7
7
|
doc?: MeshDocument;
|
|
8
|
-
status?: unknown;
|
|
9
8
|
}
|
|
10
9
|
export declare class SyncClient extends EventEmitter<SyncClientEvent> {
|
|
11
|
-
private readonly
|
|
12
|
-
private _connectingDocuments;
|
|
13
|
-
private
|
|
14
|
-
private
|
|
10
|
+
private readonly room;
|
|
11
|
+
private readonly _connectingDocuments;
|
|
12
|
+
private readonly _closingDocuments;
|
|
13
|
+
private readonly _connectedDocuments;
|
|
14
|
+
private readonly _documentStreams;
|
|
15
|
+
private readonly _documentConfigs;
|
|
16
|
+
private _started;
|
|
15
17
|
constructor({ room }: {
|
|
16
18
|
room: RoomClient;
|
|
17
19
|
});
|
|
20
|
+
start(): void;
|
|
21
|
+
dispose(): void;
|
|
18
22
|
private _unexpectedResponseError;
|
|
19
23
|
private _invoke;
|
|
20
|
-
start({ onDone, onError }?: {
|
|
21
|
-
onDone?: () => void;
|
|
22
|
-
onError?: (error: Error) => void;
|
|
23
|
-
}): void;
|
|
24
|
-
dispose(): void;
|
|
25
24
|
private _applySyncPayload;
|
|
26
|
-
|
|
27
|
-
create(path: string, json?: Record<string, any>): Promise<void>;
|
|
25
|
+
create(path: string, json?: Record<string, unknown>): Promise<void>;
|
|
28
26
|
open(path: string, { create, initialJson, schema, }?: {
|
|
29
27
|
create?: boolean;
|
|
30
|
-
initialJson?: Record<string,
|
|
28
|
+
initialJson?: Record<string, unknown>;
|
|
31
29
|
schema?: MeshSchema;
|
|
32
30
|
}): Promise<MeshDocument>;
|
|
33
31
|
close(path: string): Promise<void>;
|
|
34
32
|
sync(path: string, data: Uint8Array): Promise<void>;
|
|
35
33
|
private _consumeOpenStream;
|
|
34
|
+
private _openStream;
|
|
35
|
+
private _attachStreamConsumer;
|
|
36
|
+
_onRoomDisconnect(): Promise<void>;
|
|
37
|
+
_onRoomReconnect(): Promise<void>;
|
|
36
38
|
}
|
package/dist/node/sync-client.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SyncClient = void 0;
|
|
4
|
+
const completer_1 = require("./completer");
|
|
4
5
|
const event_emitter_1 = require("./event-emitter");
|
|
5
6
|
const schema_1 = require("./schema");
|
|
6
|
-
const room_server_client_1 = require("./room-server-client");
|
|
7
7
|
const response_1 = require("./response");
|
|
8
|
-
const
|
|
8
|
+
const room_server_client_1 = require("./room-server-client");
|
|
9
9
|
const runtime_1 = require("./runtime");
|
|
10
|
-
const
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
11
|
function normalizeSyncPath(path) {
|
|
12
12
|
let normalized = path;
|
|
13
13
|
while (normalized.startsWith("./")) {
|
|
@@ -25,7 +25,8 @@ function parseSyncOpenStateChunkHeaders(headers) {
|
|
|
25
25
|
if (headers["kind"] !== "state" ||
|
|
26
26
|
typeof headers["path"] !== "string" ||
|
|
27
27
|
typeof headers["schema"] !== "object" ||
|
|
28
|
-
headers["schema"] == null
|
|
28
|
+
headers["schema"] == null ||
|
|
29
|
+
Array.isArray(headers["schema"])) {
|
|
29
30
|
throw new room_server_client_1.RoomServerException("unexpected return type from sync.open");
|
|
30
31
|
}
|
|
31
32
|
return {
|
|
@@ -36,8 +37,7 @@ function parseSyncOpenStateChunkHeaders(headers) {
|
|
|
36
37
|
}
|
|
37
38
|
function parseSyncOpenOutputChunkHeaders(headers) {
|
|
38
39
|
const kind = headers["kind"];
|
|
39
|
-
if ((kind !== "state" && kind !== "sync") ||
|
|
40
|
-
typeof headers["path"] !== "string") {
|
|
40
|
+
if ((kind !== "state" && kind !== "sync") || typeof headers["path"] !== "string") {
|
|
41
41
|
throw new room_server_client_1.RoomServerException("unexpected return type from sync.open");
|
|
42
42
|
}
|
|
43
43
|
return {
|
|
@@ -54,7 +54,7 @@ class SyncOpenStreamState {
|
|
|
54
54
|
}
|
|
55
55
|
_enqueueChunk(chunk) {
|
|
56
56
|
const waiter = this._inputWaiters.shift();
|
|
57
|
-
if (waiter) {
|
|
57
|
+
if (waiter != null) {
|
|
58
58
|
waiter(chunk);
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
@@ -132,53 +132,51 @@ class SyncClient extends event_emitter_1.EventEmitter {
|
|
|
132
132
|
constructor({ room }) {
|
|
133
133
|
super();
|
|
134
134
|
this._connectingDocuments = {};
|
|
135
|
+
this._closingDocuments = {};
|
|
135
136
|
this._connectedDocuments = {};
|
|
136
137
|
this._documentStreams = {};
|
|
137
|
-
this.
|
|
138
|
-
this.
|
|
138
|
+
this._documentConfigs = {};
|
|
139
|
+
this._started = false;
|
|
140
|
+
this.room = room;
|
|
141
|
+
}
|
|
142
|
+
start() {
|
|
143
|
+
if (this._started) {
|
|
144
|
+
throw new room_server_client_1.RoomServerException("client already started");
|
|
145
|
+
}
|
|
146
|
+
this._started = true;
|
|
147
|
+
}
|
|
148
|
+
dispose() {
|
|
149
|
+
super.dispose();
|
|
150
|
+
for (const streamState of Object.values(this._documentStreams)) {
|
|
151
|
+
streamState.closeInputStream();
|
|
152
|
+
}
|
|
153
|
+
for (const doc of Object.values(this._connectedDocuments)) {
|
|
154
|
+
(0, runtime_1.unregisterDocument)(doc.ref.id);
|
|
155
|
+
}
|
|
156
|
+
Object.keys(this._documentStreams).forEach((key) => delete this._documentStreams[key]);
|
|
157
|
+
Object.keys(this._documentConfigs).forEach((key) => delete this._documentConfigs[key]);
|
|
158
|
+
Object.keys(this._connectedDocuments).forEach((key) => delete this._connectedDocuments[key]);
|
|
159
|
+
Object.keys(this._connectingDocuments).forEach((key) => delete this._connectingDocuments[key]);
|
|
160
|
+
Object.keys(this._closingDocuments).forEach((key) => delete this._closingDocuments[key]);
|
|
161
|
+
this._started = false;
|
|
139
162
|
}
|
|
140
163
|
_unexpectedResponseError(operation) {
|
|
141
164
|
return new room_server_client_1.RoomServerException(`unexpected return type from sync.${operation}`);
|
|
142
165
|
}
|
|
143
166
|
async _invoke(operation, input) {
|
|
144
|
-
return await this.
|
|
167
|
+
return await this.room.invoke({
|
|
145
168
|
toolkit: "sync",
|
|
146
169
|
tool: operation,
|
|
147
170
|
input,
|
|
148
171
|
});
|
|
149
172
|
}
|
|
150
|
-
start({ onDone, onError } = {}) {
|
|
151
|
-
this.client.protocol.start({ onDone, onError });
|
|
152
|
-
}
|
|
153
|
-
dispose() {
|
|
154
|
-
super.dispose();
|
|
155
|
-
for (const streamState of Object.values(this._documentStreams)) {
|
|
156
|
-
streamState.closeInputStream();
|
|
157
|
-
}
|
|
158
|
-
this._documentStreams = {};
|
|
159
|
-
for (const rc of Object.values(this._connectedDocuments)) {
|
|
160
|
-
(0, runtime_1.unregisterDocument)(rc.ref.id);
|
|
161
|
-
}
|
|
162
|
-
this._connectedDocuments = {};
|
|
163
|
-
this._connectingDocuments = {};
|
|
164
|
-
}
|
|
165
173
|
_applySyncPayload(rc, payload) {
|
|
166
|
-
const doc = rc.ref;
|
|
167
174
|
if (payload.length > 0) {
|
|
168
|
-
|
|
169
|
-
(0, runtime_1.applyBackendChanges)(doc.id, base64);
|
|
175
|
+
(0, runtime_1.applyBackendChanges)(rc.ref.id, utils_1.decoder.decode(payload));
|
|
170
176
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
doc.setSynchronizedComplete();
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
async _handleStatus(_protocol, _messageId, _type, bytes) {
|
|
177
|
-
if (!bytes) {
|
|
178
|
-
return;
|
|
177
|
+
if (!rc.ref.isSynchronized) {
|
|
178
|
+
rc.ref.setSynchronizedComplete();
|
|
179
179
|
}
|
|
180
|
-
const [header] = (0, utils_1.unpackMessage)(bytes);
|
|
181
|
-
this.emit("status", { type: "status", status: header.status });
|
|
182
180
|
}
|
|
183
181
|
async create(path, json) {
|
|
184
182
|
const normalizedPath = normalizeSyncPath(path);
|
|
@@ -190,129 +188,126 @@ class SyncClient extends event_emitter_1.EventEmitter {
|
|
|
190
188
|
});
|
|
191
189
|
}
|
|
192
190
|
async open(path, { create = true, initialJson, schema, } = {}) {
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
if (
|
|
191
|
+
const normalizedPath = normalizeSyncPath(path);
|
|
192
|
+
const closing = this._closingDocuments[normalizedPath];
|
|
193
|
+
if (closing != null) {
|
|
194
|
+
await closing;
|
|
195
|
+
}
|
|
196
|
+
const pending = this._connectingDocuments[normalizedPath];
|
|
197
|
+
if (pending != null) {
|
|
196
198
|
await pending;
|
|
197
199
|
}
|
|
198
|
-
const connected = this._connectedDocuments[
|
|
199
|
-
if (connected) {
|
|
200
|
-
connected.count
|
|
200
|
+
const connected = this._connectedDocuments[normalizedPath];
|
|
201
|
+
if (connected != null) {
|
|
202
|
+
connected.count += 1;
|
|
201
203
|
return connected.ref;
|
|
202
204
|
}
|
|
203
205
|
const connecting = new completer_1.Completer();
|
|
204
|
-
this._connectingDocuments[
|
|
205
|
-
let streamState;
|
|
206
|
-
let iterator;
|
|
206
|
+
this._connectingDocuments[normalizedPath] = connecting.fut;
|
|
207
207
|
try {
|
|
208
|
-
|
|
209
|
-
path,
|
|
208
|
+
const config = {
|
|
210
209
|
create,
|
|
211
|
-
|
|
212
|
-
schemaJson: schema == null ? null : schema.toJson(),
|
|
210
|
+
schemaJson: schema?.toJson() ?? null,
|
|
213
211
|
schemaPath: null,
|
|
212
|
+
};
|
|
213
|
+
const openResult = await this._openStream({
|
|
214
|
+
path: normalizedPath,
|
|
215
|
+
config,
|
|
216
|
+
vector: null,
|
|
214
217
|
initialJson: initialJson ?? null,
|
|
215
218
|
});
|
|
216
|
-
const
|
|
217
|
-
toolkit: "sync",
|
|
218
|
-
tool: "open",
|
|
219
|
-
input: streamState.inputStream(),
|
|
220
|
-
});
|
|
221
|
-
iterator = responseStream[Symbol.asyncIterator]();
|
|
222
|
-
const first = await iterator.next();
|
|
223
|
-
if (first.done || first.value === undefined) {
|
|
224
|
-
throw new room_server_client_1.RoomServerException("sync.open stream closed before the initial document state was returned");
|
|
225
|
-
}
|
|
226
|
-
const firstChunk = first.value;
|
|
227
|
-
if (firstChunk instanceof response_1.ErrorContent) {
|
|
228
|
-
throw new room_server_client_1.RoomServerException(firstChunk.text, firstChunk.code);
|
|
229
|
-
}
|
|
230
|
-
if (!(firstChunk instanceof response_1.BinaryContent)) {
|
|
231
|
-
throw this._unexpectedResponseError("open");
|
|
232
|
-
}
|
|
233
|
-
const stateHeaders = parseSyncOpenStateChunkHeaders(firstChunk.headers);
|
|
234
|
-
if (normalizeSyncPath(stateHeaders.path) !== path) {
|
|
235
|
-
throw new room_server_client_1.RoomServerException("sync.open stream returned a mismatched path");
|
|
236
|
-
}
|
|
219
|
+
const resolvedSchema = schema_1.MeshSchema.fromJson(openResult.stateHeaders.schema);
|
|
237
220
|
const doc = new room_server_client_1.MeshDocument({
|
|
238
|
-
schema:
|
|
221
|
+
schema: resolvedSchema,
|
|
239
222
|
sendChangesToBackend: (base64) => {
|
|
223
|
+
const currentStream = this._documentStreams[normalizedPath];
|
|
224
|
+
if (currentStream == null) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
240
227
|
try {
|
|
241
|
-
|
|
228
|
+
currentStream.queueSync(utils_1.encoder.encode(base64));
|
|
242
229
|
}
|
|
243
230
|
catch {
|
|
244
231
|
}
|
|
245
232
|
},
|
|
246
233
|
});
|
|
247
234
|
const rc = new utils_1.RefCount(doc);
|
|
248
|
-
this._connectedDocuments[
|
|
249
|
-
this.
|
|
250
|
-
this.
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
streamState,
|
|
256
|
-
|
|
235
|
+
this._connectedDocuments[normalizedPath] = rc;
|
|
236
|
+
this._documentConfigs[normalizedPath] = config;
|
|
237
|
+
this._documentStreams[normalizedPath] = openResult.streamState;
|
|
238
|
+
this._applySyncPayload(rc, openResult.firstChunk.data);
|
|
239
|
+
this._attachStreamConsumer({
|
|
240
|
+
path: normalizedPath,
|
|
241
|
+
doc: rc,
|
|
242
|
+
streamState: openResult.streamState,
|
|
243
|
+
iterator: openResult.iterator,
|
|
244
|
+
});
|
|
257
245
|
this.emit("connected", { type: "connect", doc });
|
|
258
246
|
connecting.complete(rc);
|
|
259
247
|
await doc.synchronized;
|
|
260
248
|
return doc;
|
|
261
249
|
}
|
|
262
250
|
catch (error) {
|
|
263
|
-
streamState?.closeInputStream();
|
|
264
|
-
if (iterator) {
|
|
265
|
-
await iterator.return?.();
|
|
266
|
-
}
|
|
267
251
|
connecting.completeError(error);
|
|
268
252
|
throw error;
|
|
269
253
|
}
|
|
270
254
|
finally {
|
|
271
|
-
delete this._connectingDocuments[
|
|
255
|
+
delete this._connectingDocuments[normalizedPath];
|
|
272
256
|
}
|
|
273
257
|
}
|
|
274
258
|
async close(path) {
|
|
275
|
-
|
|
276
|
-
const rc = this._connectedDocuments[
|
|
277
|
-
if (
|
|
278
|
-
throw new room_server_client_1.RoomServerException(`Not connected to ${
|
|
259
|
+
const normalizedPath = normalizeSyncPath(path);
|
|
260
|
+
const rc = this._connectedDocuments[normalizedPath];
|
|
261
|
+
if (rc == null) {
|
|
262
|
+
throw new room_server_client_1.RoomServerException(`Not connected to ${normalizedPath}`);
|
|
279
263
|
}
|
|
280
|
-
|
|
281
|
-
rc.count--;
|
|
264
|
+
rc.count -= 1;
|
|
282
265
|
if (rc.count === 0) {
|
|
283
|
-
delete this._connectedDocuments[
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
266
|
+
delete this._connectedDocuments[normalizedPath];
|
|
267
|
+
delete this._documentConfigs[normalizedPath];
|
|
268
|
+
const streamState = this._documentStreams[normalizedPath];
|
|
269
|
+
delete this._documentStreams[normalizedPath];
|
|
270
|
+
const closeFuture = (async () => {
|
|
271
|
+
if (streamState != null) {
|
|
272
|
+
streamState.closeInputStream();
|
|
273
|
+
try {
|
|
274
|
+
await streamState.wait();
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
(0, runtime_1.unregisterDocument)(rc.ref.id);
|
|
278
|
+
}
|
|
290
279
|
}
|
|
291
|
-
|
|
292
|
-
(0, runtime_1.unregisterDocument)(
|
|
280
|
+
else {
|
|
281
|
+
(0, runtime_1.unregisterDocument)(rc.ref.id);
|
|
293
282
|
}
|
|
283
|
+
})();
|
|
284
|
+
this._closingDocuments[normalizedPath] = closeFuture;
|
|
285
|
+
try {
|
|
286
|
+
await closeFuture;
|
|
294
287
|
}
|
|
295
|
-
|
|
296
|
-
|
|
288
|
+
finally {
|
|
289
|
+
if (this._closingDocuments[normalizedPath] === closeFuture) {
|
|
290
|
+
delete this._closingDocuments[normalizedPath];
|
|
291
|
+
}
|
|
297
292
|
}
|
|
298
293
|
}
|
|
299
|
-
this.emit("closed", { type: "close", doc });
|
|
294
|
+
this.emit("closed", { type: "close", doc: rc.ref });
|
|
300
295
|
}
|
|
301
296
|
async sync(path, data) {
|
|
302
|
-
|
|
303
|
-
if (
|
|
297
|
+
const normalizedPath = normalizeSyncPath(path);
|
|
298
|
+
if (this._connectedDocuments[normalizedPath] == null) {
|
|
304
299
|
throw new room_server_client_1.RoomServerException("attempted to sync to a document that is not connected");
|
|
305
300
|
}
|
|
306
|
-
const streamState = this._documentStreams[
|
|
307
|
-
if (
|
|
301
|
+
const streamState = this._documentStreams[normalizedPath];
|
|
302
|
+
if (streamState == null) {
|
|
308
303
|
throw new room_server_client_1.RoomServerException("attempted to sync to a document that is not connected");
|
|
309
304
|
}
|
|
310
305
|
streamState.queueSync(data);
|
|
311
306
|
}
|
|
312
|
-
async _consumeOpenStream(
|
|
307
|
+
async _consumeOpenStream({ path, rc, iterator, streamState, }) {
|
|
313
308
|
try {
|
|
314
309
|
while (true) {
|
|
315
|
-
const next = await
|
|
310
|
+
const next = await iterator.next();
|
|
316
311
|
if (next.done || next.value === undefined) {
|
|
317
312
|
return;
|
|
318
313
|
}
|
|
@@ -330,15 +325,99 @@ class SyncClient extends event_emitter_1.EventEmitter {
|
|
|
330
325
|
throw this._unexpectedResponseError("open");
|
|
331
326
|
}
|
|
332
327
|
const headers = parseSyncOpenOutputChunkHeaders(chunk.headers);
|
|
333
|
-
if (normalizeSyncPath(headers.path) !==
|
|
328
|
+
if (normalizeSyncPath(headers.path) !== path) {
|
|
334
329
|
throw new room_server_client_1.RoomServerException("sync.open stream returned a mismatched path");
|
|
335
330
|
}
|
|
336
|
-
this._applySyncPayload(
|
|
331
|
+
this._applySyncPayload(rc, chunk.data);
|
|
337
332
|
}
|
|
338
333
|
}
|
|
339
334
|
finally {
|
|
340
|
-
|
|
341
|
-
await
|
|
335
|
+
streamState.closeInputStream();
|
|
336
|
+
await iterator.return?.();
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
async _openStream({ path, config, vector, initialJson, }) {
|
|
340
|
+
const streamState = new SyncOpenStreamState({
|
|
341
|
+
path,
|
|
342
|
+
create: config.create,
|
|
343
|
+
vector,
|
|
344
|
+
schemaJson: config.schemaJson,
|
|
345
|
+
schemaPath: config.schemaPath,
|
|
346
|
+
initialJson,
|
|
347
|
+
});
|
|
348
|
+
let iterator;
|
|
349
|
+
try {
|
|
350
|
+
const responseStream = await this.room.invokeStream({
|
|
351
|
+
toolkit: "sync",
|
|
352
|
+
tool: "open",
|
|
353
|
+
input: streamState.inputStream(),
|
|
354
|
+
});
|
|
355
|
+
iterator = responseStream[Symbol.asyncIterator]();
|
|
356
|
+
const first = await iterator.next();
|
|
357
|
+
if (first.done || first.value === undefined) {
|
|
358
|
+
throw new room_server_client_1.RoomServerException("sync.open stream closed before the initial document state was returned");
|
|
359
|
+
}
|
|
360
|
+
const firstChunk = first.value;
|
|
361
|
+
if (firstChunk instanceof response_1.ErrorContent) {
|
|
362
|
+
throw new room_server_client_1.RoomServerException(firstChunk.text, firstChunk.code);
|
|
363
|
+
}
|
|
364
|
+
if (!(firstChunk instanceof response_1.BinaryContent)) {
|
|
365
|
+
throw this._unexpectedResponseError("open");
|
|
366
|
+
}
|
|
367
|
+
const stateHeaders = parseSyncOpenStateChunkHeaders(firstChunk.headers);
|
|
368
|
+
if (normalizeSyncPath(stateHeaders.path) !== path) {
|
|
369
|
+
throw new room_server_client_1.RoomServerException("sync.open stream returned a mismatched path");
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
streamState,
|
|
373
|
+
iterator,
|
|
374
|
+
stateHeaders,
|
|
375
|
+
firstChunk,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
streamState.closeInputStream();
|
|
380
|
+
if (iterator != null) {
|
|
381
|
+
await iterator.return?.();
|
|
382
|
+
}
|
|
383
|
+
throw error;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
_attachStreamConsumer({ path, doc, streamState, iterator, }) {
|
|
387
|
+
streamState.attachTask(this._consumeOpenStream({
|
|
388
|
+
path,
|
|
389
|
+
rc: doc,
|
|
390
|
+
iterator,
|
|
391
|
+
streamState,
|
|
392
|
+
}));
|
|
393
|
+
}
|
|
394
|
+
async _onRoomDisconnect() {
|
|
395
|
+
const openStreams = Object.values(this._documentStreams);
|
|
396
|
+
Object.keys(this._documentStreams).forEach((key) => delete this._documentStreams[key]);
|
|
397
|
+
for (const streamState of openStreams) {
|
|
398
|
+
streamState.closeInputStream();
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
async _onRoomReconnect() {
|
|
402
|
+
for (const [path, ref] of Object.entries(this._connectedDocuments)) {
|
|
403
|
+
const config = this._documentConfigs[path];
|
|
404
|
+
if (config == null) {
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
const openResult = await this._openStream({
|
|
408
|
+
path,
|
|
409
|
+
config,
|
|
410
|
+
vector: ref.ref.getStateVector(),
|
|
411
|
+
initialJson: null,
|
|
412
|
+
});
|
|
413
|
+
this._documentStreams[path] = openResult.streamState;
|
|
414
|
+
this._applySyncPayload(ref, openResult.firstChunk.data);
|
|
415
|
+
this._attachStreamConsumer({
|
|
416
|
+
path,
|
|
417
|
+
doc: ref,
|
|
418
|
+
streamState: openResult.streamState,
|
|
419
|
+
iterator: openResult.iterator,
|
|
420
|
+
});
|
|
342
421
|
}
|
|
343
422
|
}
|
|
344
423
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meshagent/meshagent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.0",
|
|
4
4
|
"description": "Meshagent Client",
|
|
5
5
|
"homepage": "https://github.com/meshagent/meshagent-ts",
|
|
6
6
|
"scripts": {
|
|
@@ -11,10 +11,13 @@
|
|
|
11
11
|
"author": "Meshagent Software",
|
|
12
12
|
"license": "Apache-2.0",
|
|
13
13
|
"main": "./dist/node/index.js",
|
|
14
|
+
"types": "./dist/node/index.d.ts",
|
|
14
15
|
"exports": {
|
|
15
16
|
".": {
|
|
16
|
-
"
|
|
17
|
+
"types": "./dist/node/index.d.ts",
|
|
18
|
+
"import": "./dist/esm/index.js",
|
|
17
19
|
"browser": "./dist/browser/index.js",
|
|
20
|
+
"require": "./dist/node/index.js",
|
|
18
21
|
"default": "./dist/node/index.js"
|
|
19
22
|
},
|
|
20
23
|
"./package.json": "./package.json"
|
|
@@ -53,4 +56,4 @@
|
|
|
53
56
|
"overrides": {
|
|
54
57
|
"rollup": "4.52.5"
|
|
55
58
|
}
|
|
56
|
-
}
|
|
59
|
+
}
|