@manifest-editor/server-vault 1.4.3 → 2.0.1-next.0.2841cdd

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/index.cjs CHANGED
@@ -1,240 +1,233 @@
1
- "use strict";
1
+ //#region rolldown:runtime
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
8
  var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
- var __publicField = (obj, key, value) => {
31
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
- return value;
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
33
17
  };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ let __iiif_helpers_vault = require("@iiif/helpers/vault");
25
+ let ws = require("ws");
26
+ ws = __toESM(ws);
27
+ let uuid = require("uuid");
28
+ let timers = require("timers");
29
+ let http = require("http");
30
+
31
+ //#region \0@oxc-project+runtime@0.97.0/helpers/typeof.js
32
+ function _typeof(o) {
33
+ "@babel/helpers - typeof";
34
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
35
+ return typeof o$1;
36
+ } : function(o$1) {
37
+ return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
38
+ }, _typeof(o);
39
+ }
34
40
 
35
- // src/index.ts
36
- var src_exports = {};
37
- __export(src_exports, {
38
- MultiVaultServer: () => MultiVaultServer,
39
- ServerVault: () => ServerVault
40
- });
41
- module.exports = __toCommonJS(src_exports);
41
+ //#endregion
42
+ //#region \0@oxc-project+runtime@0.97.0/helpers/toPrimitive.js
43
+ function toPrimitive(t, r) {
44
+ if ("object" != _typeof(t) || !t) return t;
45
+ var e = t[Symbol.toPrimitive];
46
+ if (void 0 !== e) {
47
+ var i = e.call(t, r || "default");
48
+ if ("object" != _typeof(i)) return i;
49
+ throw new TypeError("@@toPrimitive must return a primitive value.");
50
+ }
51
+ return ("string" === r ? String : Number)(t);
52
+ }
42
53
 
43
- // src/server-vault.ts
44
- var import_vault = require("@iiif/helpers/vault");
45
- var import_ws = __toESM(require("ws"), 1);
46
- var import_uuid = require("uuid");
47
- var import_timers = require("timers");
48
- var GenesisId = "@genesis";
54
+ //#endregion
55
+ //#region \0@oxc-project+runtime@0.97.0/helpers/toPropertyKey.js
56
+ function toPropertyKey(t) {
57
+ var i = toPrimitive(t, "string");
58
+ return "symbol" == _typeof(i) ? i : i + "";
59
+ }
60
+
61
+ //#endregion
62
+ //#region \0@oxc-project+runtime@0.97.0/helpers/defineProperty.js
63
+ function _defineProperty(e, r, t) {
64
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
65
+ value: t,
66
+ enumerable: !0,
67
+ configurable: !0,
68
+ writable: !0
69
+ }) : e[r] = t, e;
70
+ }
71
+
72
+ //#endregion
73
+ //#region src/server-vault.ts
74
+ const GenesisId = "@genesis";
49
75
  var ServerVault = class {
50
- constructor(options = {}) {
51
- __publicField(this, "vault");
52
- __publicField(this, "ws");
53
- __publicField(this, "lastActionId", GenesisId);
54
- __publicField(this, "pingInterval");
55
- __publicField(this, "_handleMessage", /* @__PURE__ */ new Map());
56
- __publicField(this, "_handleOpen", /* @__PURE__ */ new Map());
57
- __publicField(this, "_handleClose", /* @__PURE__ */ new Map());
58
- __publicField(this, "setupWebSocket", (socket) => {
59
- socket.isAlive = true;
60
- socket.on("pong", () => {
61
- socket.isAlive = true;
62
- });
63
- socket.on("open", this.handleOpen(socket));
64
- socket.on("message", this.handleMessage(socket));
65
- socket.on("close", this.handleClose(socket));
66
- socket.send(this.createMessage("init-response", { data: this.vault.getState() }));
67
- });
68
- __publicField(this, "handleMessage", (socket) => {
69
- if (this._handleMessage.has(socket)) {
70
- return this._handleMessage.get(socket);
71
- }
72
- const handler = (data, isBinary) => {
73
- const parsed = JSON.parse(data.toString());
74
- if (parsed._type === "init-request") {
75
- socket.send(this.createMessage("init-response", { data: this.vault.getState() }));
76
- }
77
- if (parsed._type === "vault-action") {
78
- try {
79
- this.vault.dispatch(parsed.action);
80
- } catch (e) {
81
- socket.send(
82
- this.createMessage("vault-action-rejection", {
83
- action: parsed._id
84
- })
85
- );
86
- return;
87
- }
88
- this.lastActionId = parsed._id;
89
- this.rebroadcast(socket, data, parsed, isBinary);
90
- }
91
- };
92
- this._handleMessage.set(socket, handler);
93
- return handler;
94
- });
95
- __publicField(this, "send", (data) => {
96
- this.ws.clients.forEach(function each(client) {
97
- if (client.readyState === import_ws.default.OPEN) {
98
- client.send(data, { binary: true });
99
- }
100
- });
101
- });
102
- __publicField(this, "rebroadcast", (source, data, action, isBinary = true) => {
103
- this.ws.clients.forEach((client) => {
104
- if (client !== source && client.readyState === import_ws.default.OPEN) {
105
- client.send(data, { binary: isBinary });
106
- } else {
107
- client.send(
108
- this.createMessage("vault-action-confirmation", {
109
- action: action._id
110
- })
111
- );
112
- }
113
- });
114
- });
115
- __publicField(this, "handleOpen", (socket) => {
116
- if (this._handleOpen.has(socket)) {
117
- return this._handleOpen.get(socket);
118
- }
119
- const handler = () => {
120
- };
121
- this._handleOpen.set(socket, handler);
122
- return handler;
123
- });
124
- __publicField(this, "handleClose", (socket) => {
125
- if (this._handleClose.has(socket)) {
126
- return this._handleClose.get(socket);
127
- }
128
- const handler = () => {
129
- };
130
- this._handleClose.set(socket, handler);
131
- return handler;
132
- });
133
- __publicField(this, "createMessage", (type, message) => {
134
- return JSON.stringify({
135
- _id: (0, import_uuid.v4)(),
136
- _type: type,
137
- _lastActionId: this.lastActionId,
138
- ...message
139
- });
140
- });
141
- this.vault = new import_vault.Vault();
142
- this.ws = new import_ws.WebSocketServer({ noServer: true });
143
- this.ws.on("connection", this.setupWebSocket);
144
- this.pingInterval = (0, import_timers.setInterval)(() => {
145
- this.ws.clients.forEach((socket) => {
146
- if (socket.isAlive === false) {
147
- return socket.terminate();
148
- }
149
- socket.isAlive = false;
150
- socket.ping();
151
- });
152
- }, options.pingTimeout || 3e4);
153
- this.ws.on("close", () => {
154
- (0, import_timers.clearInterval)(this.pingInterval);
155
- if (options.onClose) {
156
- options.onClose();
157
- }
158
- });
159
- this.ws.on("error", (err) => {
160
- });
161
- }
162
- async close() {
163
- clearTimeout(this.pingInterval);
164
- return new Promise((resolve, error) => {
165
- this.ws.close((err) => {
166
- if (err) {
167
- error(err);
168
- }
169
- resolve();
170
- });
171
- });
172
- }
76
+ constructor(options = {}) {
77
+ _defineProperty(this, "vault", void 0);
78
+ _defineProperty(this, "ws", void 0);
79
+ _defineProperty(this, "lastActionId", GenesisId);
80
+ _defineProperty(this, "pingInterval", void 0);
81
+ _defineProperty(this, "_handleMessage", /* @__PURE__ */ new Map());
82
+ _defineProperty(this, "_handleOpen", /* @__PURE__ */ new Map());
83
+ _defineProperty(this, "_handleClose", /* @__PURE__ */ new Map());
84
+ _defineProperty(this, "setupWebSocket", (socket) => {
85
+ socket.isAlive = true;
86
+ socket.on("pong", () => {
87
+ socket.isAlive = true;
88
+ });
89
+ socket.on("open", this.handleOpen(socket));
90
+ socket.on("message", this.handleMessage(socket));
91
+ socket.on("close", this.handleClose(socket));
92
+ socket.send(this.createMessage("init-response", { data: this.vault.getState() }));
93
+ });
94
+ _defineProperty(this, "handleMessage", (socket) => {
95
+ if (this._handleMessage.has(socket)) return this._handleMessage.get(socket);
96
+ const handler = (data, isBinary) => {
97
+ const parsed = JSON.parse(data.toString());
98
+ if (parsed._type === "init-request") socket.send(this.createMessage("init-response", { data: this.vault.getState() }));
99
+ if (parsed._type === "vault-action") {
100
+ try {
101
+ this.vault.dispatch(parsed.action);
102
+ } catch (e) {
103
+ socket.send(this.createMessage("vault-action-rejection", { action: parsed._id }));
104
+ return;
105
+ }
106
+ this.lastActionId = parsed._id;
107
+ this.rebroadcast(socket, data, parsed, isBinary);
108
+ }
109
+ };
110
+ this._handleMessage.set(socket, handler);
111
+ return handler;
112
+ });
113
+ _defineProperty(this, "send", (data) => {
114
+ this.ws.clients.forEach(function each(client) {
115
+ if (client.readyState === ws.default.OPEN) client.send(data, { binary: true });
116
+ });
117
+ });
118
+ _defineProperty(this, "rebroadcast", (source, data, action, isBinary = true) => {
119
+ this.ws.clients.forEach((client) => {
120
+ if (client !== source && client.readyState === ws.default.OPEN) client.send(data, { binary: isBinary });
121
+ else client.send(this.createMessage("vault-action-confirmation", { action: action._id }));
122
+ });
123
+ });
124
+ _defineProperty(this, "handleOpen", (socket) => {
125
+ if (this._handleOpen.has(socket)) return this._handleOpen.get(socket);
126
+ const handler = () => {};
127
+ this._handleOpen.set(socket, handler);
128
+ return handler;
129
+ });
130
+ _defineProperty(this, "handleClose", (socket) => {
131
+ if (this._handleClose.has(socket)) return this._handleClose.get(socket);
132
+ const handler = () => {};
133
+ this._handleClose.set(socket, handler);
134
+ return handler;
135
+ });
136
+ _defineProperty(this, "createMessage", (type, message) => {
137
+ return JSON.stringify({
138
+ _id: (0, uuid.v4)(),
139
+ _type: type,
140
+ _lastActionId: this.lastActionId,
141
+ ...message
142
+ });
143
+ });
144
+ this.vault = new __iiif_helpers_vault.Vault();
145
+ this.ws = new ws.WebSocketServer({ noServer: true });
146
+ this.ws.on("connection", this.setupWebSocket);
147
+ this.pingInterval = (0, timers.setInterval)(() => {
148
+ this.ws.clients.forEach((socket) => {
149
+ if (socket.isAlive === false) return socket.terminate();
150
+ socket.isAlive = false;
151
+ socket.ping();
152
+ });
153
+ }, options.pingTimeout || 3e4);
154
+ this.ws.on("close", () => {
155
+ (0, timers.clearInterval)(this.pingInterval);
156
+ if (options.onClose) options.onClose();
157
+ });
158
+ this.ws.on("error", (err) => {});
159
+ }
160
+ async close() {
161
+ clearTimeout(this.pingInterval);
162
+ return new Promise((resolve, error) => {
163
+ this.ws.close((err) => {
164
+ if (err) error(err);
165
+ resolve();
166
+ });
167
+ });
168
+ }
173
169
  };
174
170
 
175
- // src/server.ts
176
- var import_http = require("http");
171
+ //#endregion
172
+ //#region src/server.ts
177
173
  var MultiVaultServer = class {
178
- constructor(server) {
179
- __publicField(this, "server");
180
- __publicField(this, "vaults", /* @__PURE__ */ new Map());
181
- __publicField(this, "handleRequest", (request, response) => {
182
- if (request.url === "/vault") {
183
- const vaults = Array.from(this.vaults.keys());
184
- const json = JSON.stringify({ vaults });
185
- response.writeHead(200, {
186
- "Content-Length": Buffer.byteLength(json),
187
- "Content-Type": "application/json"
188
- });
189
- response.write(json);
190
- response.end();
191
- return;
192
- }
193
- response.writeHead(404);
194
- response.end();
195
- });
196
- __publicField(this, "handleUpgrade", (request, socket, head) => {
197
- console.log("ws.url", request.url);
198
- const pathname = request.url;
199
- if (pathname && pathname.startsWith("/vault")) {
200
- const vaultId = pathname.replace("/vault/", "");
201
- let vault = this.vaults.get(vaultId);
202
- if (!vault) {
203
- const newVault = new ServerVault();
204
- console.log("new vault", vaultId);
205
- this.vaults.set(vaultId, newVault);
206
- vault = newVault;
207
- }
208
- if (vault) {
209
- const theVault = vault;
210
- theVault.ws.handleUpgrade(request, socket, head, (ws) => {
211
- console.log("new client", vaultId);
212
- theVault.ws.emit("connection", ws, request);
213
- theVault.ws.on("close", () => {
214
- if (theVault.ws.clients.size === 0) {
215
- console.log("destroying vault", vaultId);
216
- this.vaults.delete(vaultId);
217
- }
218
- });
219
- });
220
- } else {
221
- socket.destroy();
222
- }
223
- return;
224
- }
225
- socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
226
- socket.destroy();
227
- });
228
- this.server = server || (0, import_http.createServer)();
229
- this.server.on("upgrade", this.handleUpgrade);
230
- this.server.on("request", this.handleRequest);
231
- }
232
- listen(port, hostname, backlog, listeningListener) {
233
- this.server.listen(port, hostname, backlog, listeningListener);
234
- }
174
+ constructor(server) {
175
+ _defineProperty(this, "server", void 0);
176
+ _defineProperty(this, "vaults", /* @__PURE__ */ new Map());
177
+ _defineProperty(this, "handleRequest", (request, response) => {
178
+ if (request.url === "/vault") {
179
+ const vaults = Array.from(this.vaults.keys());
180
+ const json = JSON.stringify({ vaults });
181
+ response.writeHead(200, {
182
+ "Content-Length": Buffer.byteLength(json),
183
+ "Content-Type": "application/json"
184
+ });
185
+ response.write(json);
186
+ response.end();
187
+ return;
188
+ }
189
+ response.writeHead(404);
190
+ response.end();
191
+ });
192
+ _defineProperty(this, "handleUpgrade", (request, socket, head) => {
193
+ console.log("ws.url", request.url);
194
+ const pathname = request.url;
195
+ if (pathname && pathname.startsWith("/vault")) {
196
+ const vaultId = pathname.replace("/vault/", "");
197
+ let vault = this.vaults.get(vaultId);
198
+ if (!vault) {
199
+ const newVault = new ServerVault();
200
+ console.log("new vault", vaultId);
201
+ this.vaults.set(vaultId, newVault);
202
+ vault = newVault;
203
+ }
204
+ if (vault) {
205
+ const theVault = vault;
206
+ theVault.ws.handleUpgrade(request, socket, head, (ws$1) => {
207
+ console.log("new client", vaultId);
208
+ theVault.ws.emit("connection", ws$1, request);
209
+ theVault.ws.on("close", () => {
210
+ if (theVault.ws.clients.size === 0) {
211
+ console.log("destroying vault", vaultId);
212
+ this.vaults.delete(vaultId);
213
+ }
214
+ });
215
+ });
216
+ } else socket.destroy();
217
+ return;
218
+ }
219
+ socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
220
+ socket.destroy();
221
+ });
222
+ this.server = server || (0, http.createServer)();
223
+ this.server.on("upgrade", this.handleUpgrade);
224
+ this.server.on("request", this.handleRequest);
225
+ }
226
+ listen(port, hostname, backlog, listeningListener) {
227
+ this.server.listen(port, hostname, backlog, listeningListener);
228
+ }
235
229
  };
236
- // Annotate the CommonJS export names for ESM import in node:
237
- 0 && (module.exports = {
238
- MultiVaultServer,
239
- ServerVault
240
- });
230
+
231
+ //#endregion
232
+ exports.MultiVaultServer = MultiVaultServer;
233
+ exports.ServerVault = ServerVault;
package/dist/index.d.cts CHANGED
@@ -1,85 +1,88 @@
1
- import { Vault, AllActions, IIIFStore } from '@iiif/helpers/vault';
2
- import { BatchAction } from '@iiif/helpers/vault/actions';
3
- import { Collection, Manifest } from '@iiif/presentation-3';
4
- import WebSocket, { WebSocketServer, RawData } from 'ws';
5
- import { Server, IncomingMessage } from 'http';
6
- import { Socket } from 'net';
1
+ import { AllActions, IIIFStore, Vault } from "@iiif/helpers/vault";
2
+ import { BatchAction } from "@iiif/helpers/vault/actions";
3
+ import { Collection, Manifest } from "@iiif/presentation-3";
4
+ import WebSocket, { RawData, WebSocketServer } from "ws";
5
+ import { IncomingMessage, Server } from "http";
6
+ import { Socket } from "net";
7
7
 
8
+ //#region src/server-vault.d.ts
8
9
  type RemoteAction = {
9
- _id: string;
10
- _type: "vault-action";
11
- _lastActionId: string;
12
- action: AllActions | BatchAction;
10
+ _id: string;
11
+ _type: "vault-action";
12
+ _lastActionId: string;
13
+ action: AllActions | BatchAction;
13
14
  };
14
15
  type ClientInitAction = {
15
- _id: string;
16
- _type: "init-response";
17
- _lastActionId: string;
18
- data: IIIFStore;
16
+ _id: string;
17
+ _type: "init-response";
18
+ _lastActionId: string;
19
+ data: IIIFStore;
19
20
  };
20
21
  type ClientInitRequestAction = {
21
- _type: "init-request";
22
+ _type: "init-request";
22
23
  };
23
24
  type RemoteActionConfirmation = {
24
- _id: string;
25
- _type: "vault-action-confirmation";
26
- _lastActionId: string;
27
- action: string;
25
+ _id: string;
26
+ _type: "vault-action-confirmation";
27
+ _lastActionId: string;
28
+ action: string;
28
29
  };
29
30
  type RemoteActionRejection = {
30
- _id: string;
31
- _type: "vault-action-rejection";
32
- _lastActionId: string;
33
- action: string;
31
+ _id: string;
32
+ _type: "vault-action-rejection";
33
+ _lastActionId: string;
34
+ action: string;
34
35
  };
35
36
  type InitialiseWithResourceAction = {
36
- _id: string;
37
- _type: "initialise-with-resource";
38
- _lastActionId: string;
39
- resource: Collection | Manifest;
37
+ _id: string;
38
+ _type: "initialise-with-resource";
39
+ _lastActionId: string;
40
+ resource: Collection | Manifest;
40
41
  };
41
42
  type EmptyVaultResponse = {
42
- _id: string;
43
- _type: "empty-vault-response";
44
- _lastActionId: string;
43
+ _id: string;
44
+ _type: "empty-vault-response";
45
+ _lastActionId: string;
45
46
  };
46
47
  type ClientAction = RemoteAction | ClientInitRequestAction | InitialiseWithResourceAction;
47
48
  type ServerAction = RemoteAction | RemoteActionConfirmation | RemoteActionRejection | ClientInitAction | EmptyVaultResponse;
48
49
  declare module "ws" {
49
- interface WebSocket {
50
- isAlive: boolean;
51
- }
50
+ interface WebSocket {
51
+ isAlive: boolean;
52
+ }
52
53
  }
53
54
  interface ServerVaultOptions {
54
- pingTimeout?: number;
55
- onClose?: () => void;
55
+ pingTimeout?: number;
56
+ onClose?: () => void;
56
57
  }
57
58
  declare class ServerVault {
58
- vault: Vault;
59
- ws: WebSocketServer;
60
- lastActionId: string;
61
- pingInterval: NodeJS.Timeout;
62
- private _handleMessage;
63
- private _handleOpen;
64
- private _handleClose;
65
- constructor(options?: ServerVaultOptions);
66
- close(): Promise<void>;
67
- setupWebSocket: (socket: WebSocket.WebSocket) => void;
68
- handleMessage: (socket: WebSocket) => any;
69
- send: (data: RawData) => void;
70
- rebroadcast: (source: WebSocket, data: RawData, action: RemoteAction, isBinary?: boolean) => void;
71
- handleOpen: (socket: WebSocket) => any;
72
- handleClose: (socket: WebSocket) => any;
73
- createMessage: (type: string, message: any) => string;
59
+ vault: Vault;
60
+ ws: WebSocketServer;
61
+ lastActionId: string;
62
+ pingInterval: NodeJS.Timeout;
63
+ private _handleMessage;
64
+ private _handleOpen;
65
+ private _handleClose;
66
+ constructor(options?: ServerVaultOptions);
67
+ close(): Promise<void>;
68
+ setupWebSocket: (socket: WebSocket.WebSocket) => void;
69
+ handleMessage: (socket: WebSocket) => any;
70
+ send: (data: RawData) => void;
71
+ rebroadcast: (source: WebSocket, data: RawData, action: RemoteAction, isBinary?: boolean) => void;
72
+ handleOpen: (socket: WebSocket) => any;
73
+ handleClose: (socket: WebSocket) => any;
74
+ createMessage: (type: string, message: any) => string;
74
75
  }
75
-
76
+ //#endregion
77
+ //#region src/server.d.ts
76
78
  declare class MultiVaultServer {
77
- server: Server;
78
- vaults: Map<string, ServerVault>;
79
- constructor(server?: Server);
80
- listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
81
- handleRequest: (request: IncomingMessage, response: any) => void;
82
- handleUpgrade: (request: IncomingMessage, socket: Socket, head: Buffer) => void;
79
+ server: Server;
80
+ vaults: Map<string, ServerVault>;
81
+ constructor(server?: Server);
82
+ listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
83
+ handleRequest: (request: IncomingMessage, response: any) => void;
84
+ handleUpgrade: (request: IncomingMessage, socket: Socket, head: Buffer) => void;
83
85
  }
84
-
85
- export { type ClientAction, MultiVaultServer, type ServerAction, ServerVault, type ServerVaultOptions };
86
+ //#endregion
87
+ export { ClientAction, MultiVaultServer, ServerAction, ServerVault, ServerVaultOptions };
88
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/server-vault.ts","../src/server.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAQK,YAAA;;;;EAAA,MAAA,EAIK,UAJO,GAIM,WAAb;AAAwB,CAAA;AASjB,KAJZ,gBAAA,GAOA;EAIA,GAAA,EAAA,MAAA;EAOA,KAAA,EAAA,eAAA;EAOA,aAAA,EAAA,MAAA;EAOA,IAAA,EA5BG,SA4BH;AAML,CAAA;KA/BK,uBAAA,GA+BsB;EAAe,KAAA,EAAA,cAAA;CAA0B;KA3B/D,wBAAA,GA2B2F;EAEpF,GAAA,EAAA,MAAA;EACR,KAAA,EAAA,2BAAA;EACA,aAAA,EAAA,MAAA;EACA,MAAA,EAAA,MAAA;CACA;KA1BC,qBAAA,GA2BD;EAAkB,GAAA,EAAA,MAAA;EAAC,KAAA,EAAA,wBAAA;EAAA,aAAA,EAAA,MAAA;QAAA,EAAA,MAAA;CAAA;KApBlB,4BAAA,GAoBkB;EASN,GAAA,EAAA,MAAA;EAKJ,KAAA,EAAA,0BAAW;EACf,aAAA,EAAA,MAAA;EACH,QAAA,EAhCM,UAgCN,GAhCmB,QAgCnB;CAEU;KA/BX,kBAAA,GAqCkB;EA8BV,GAAA,EAAA,MAAA;EAae,KAAA,EAAU,sBAAA;EAYX,aAAA,EAAA,MAAA;CAkCX;AAQS,KAhIb,YAAA,GAAe,YAgIF,GAhIiB,uBAgIjB,GAhI2C,4BAgI3C;AAAiB,KA9H9B,YAAA,GACR,YA6HsC,GA5HtC,wBA4HsC,GA3HtC,qBA2HsC,GA1HtC,gBA0HsC,GAzHtC,kBAyHsC;eAAiB,IAAA,CAAA;EAcnC,UAAA,SAAA,CAAA;IAaC,OAAA,EAAA,OAAA;EAAS;;UA3IjB,kBAAA;;ECnEJ,OAAA,CAAA,EAAA,GAAA,GAAA,IAAgB;;AAEP,cDsET,WAAA,CCtES;EAAZ,KAAA,EDuED,KCvEC;EACa,EAAA,EDuEjB,eCvEiB;EAUK,YAAA,EAAA,MAAA;EAoBA,YAAA,ED2CZ,MAAA,CAAO,OC3CK;EAAyB,QAAA,cAAA;EAAc,QAAA,WAAA;EAAM,QAAA,YAAA;wBDiDlD;WA8BV;2BAae,SAAA,CAAU;0BAYX;eAkCX;wBAQS,iBAAiB,iBAAiB;uBAcnC;wBAaC;;;;;cC9MZ,gBAAA;UACH;UACA,YAAY;uBACC;;EDClB,aAAA,EAAY,CAAA,OAAA,ECSW,eDLL,EAAA,QAAW,EAAA,GAAA,EAAA,GAAA,IAAA;EAK7B,aAAA,EAAA,CAAA,OAAgB,ECoBO,eDhBX,EAAA,MAAA,ECgBoC,MDhBpC,EAAA,IAAA,ECgBkD,MDhBlD,EAAA,GAAA,IAAA;AAAA"}
@@ -0,0 +1,88 @@
1
+ import { AllActions, IIIFStore, Vault } from "@iiif/helpers/vault";
2
+ import WebSocket, { RawData, WebSocketServer } from "ws";
3
+ import { IncomingMessage, Server } from "http";
4
+ import { BatchAction } from "@iiif/helpers/vault/actions";
5
+ import { Collection, Manifest } from "@iiif/presentation-3";
6
+ import { Socket } from "net";
7
+
8
+ //#region src/server-vault.d.ts
9
+ type RemoteAction = {
10
+ _id: string;
11
+ _type: "vault-action";
12
+ _lastActionId: string;
13
+ action: AllActions | BatchAction;
14
+ };
15
+ type ClientInitAction = {
16
+ _id: string;
17
+ _type: "init-response";
18
+ _lastActionId: string;
19
+ data: IIIFStore;
20
+ };
21
+ type ClientInitRequestAction = {
22
+ _type: "init-request";
23
+ };
24
+ type RemoteActionConfirmation = {
25
+ _id: string;
26
+ _type: "vault-action-confirmation";
27
+ _lastActionId: string;
28
+ action: string;
29
+ };
30
+ type RemoteActionRejection = {
31
+ _id: string;
32
+ _type: "vault-action-rejection";
33
+ _lastActionId: string;
34
+ action: string;
35
+ };
36
+ type InitialiseWithResourceAction = {
37
+ _id: string;
38
+ _type: "initialise-with-resource";
39
+ _lastActionId: string;
40
+ resource: Collection | Manifest;
41
+ };
42
+ type EmptyVaultResponse = {
43
+ _id: string;
44
+ _type: "empty-vault-response";
45
+ _lastActionId: string;
46
+ };
47
+ type ClientAction = RemoteAction | ClientInitRequestAction | InitialiseWithResourceAction;
48
+ type ServerAction = RemoteAction | RemoteActionConfirmation | RemoteActionRejection | ClientInitAction | EmptyVaultResponse;
49
+ declare module "ws" {
50
+ interface WebSocket {
51
+ isAlive: boolean;
52
+ }
53
+ }
54
+ interface ServerVaultOptions {
55
+ pingTimeout?: number;
56
+ onClose?: () => void;
57
+ }
58
+ declare class ServerVault {
59
+ vault: Vault;
60
+ ws: WebSocketServer;
61
+ lastActionId: string;
62
+ pingInterval: NodeJS.Timeout;
63
+ private _handleMessage;
64
+ private _handleOpen;
65
+ private _handleClose;
66
+ constructor(options?: ServerVaultOptions);
67
+ close(): Promise<void>;
68
+ setupWebSocket: (socket: WebSocket.WebSocket) => void;
69
+ handleMessage: (socket: WebSocket) => any;
70
+ send: (data: RawData) => void;
71
+ rebroadcast: (source: WebSocket, data: RawData, action: RemoteAction, isBinary?: boolean) => void;
72
+ handleOpen: (socket: WebSocket) => any;
73
+ handleClose: (socket: WebSocket) => any;
74
+ createMessage: (type: string, message: any) => string;
75
+ }
76
+ //#endregion
77
+ //#region src/server.d.ts
78
+ declare class MultiVaultServer {
79
+ server: Server;
80
+ vaults: Map<string, ServerVault>;
81
+ constructor(server?: Server);
82
+ listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
83
+ handleRequest: (request: IncomingMessage, response: any) => void;
84
+ handleUpgrade: (request: IncomingMessage, socket: Socket, head: Buffer) => void;
85
+ }
86
+ //#endregion
87
+ export { ClientAction, MultiVaultServer, ServerAction, ServerVault, ServerVaultOptions };
88
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/server-vault.ts","../src/server.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAQK,YAAA;;;;EAAA,MAAA,EAIK,UAJO,GAIM,WAAb;AAAwB,CAAA;AASjB,KAJZ,gBAAA,GAOA;EAIA,GAAA,EAAA,MAAA;EAOA,KAAA,EAAA,eAAA;EAOA,aAAA,EAAA,MAAA;EAOA,IAAA,EA5BG,SA4BH;AAML,CAAA;KA/BK,uBAAA,GA+BsB;EAAe,KAAA,EAAA,cAAA;CAA0B;KA3B/D,wBAAA,GA2B2F;EAEpF,GAAA,EAAA,MAAA;EACR,KAAA,EAAA,2BAAA;EACA,aAAA,EAAA,MAAA;EACA,MAAA,EAAA,MAAA;CACA;KA1BC,qBAAA,GA2BD;EAAkB,GAAA,EAAA,MAAA;EAAC,KAAA,EAAA,wBAAA;EAAA,aAAA,EAAA,MAAA;QAAA,EAAA,MAAA;CAAA;KApBlB,4BAAA,GAoBkB;EASN,GAAA,EAAA,MAAA;EAKJ,KAAA,EAAA,0BAAW;EACf,aAAA,EAAA,MAAA;EACH,QAAA,EAhCM,UAgCN,GAhCmB,QAgCnB;CAEU;KA/BX,kBAAA,GAqCkB;EA8BV,GAAA,EAAA,MAAA;EAae,KAAA,EAAU,sBAAA;EAYX,aAAA,EAAA,MAAA;CAkCX;AAQS,KAhIb,YAAA,GAAe,YAgIF,GAhIiB,uBAgIjB,GAhI2C,4BAgI3C;AAAiB,KA9H9B,YAAA,GACR,YA6HsC,GA5HtC,wBA4HsC,GA3HtC,qBA2HsC,GA1HtC,gBA0HsC,GAzHtC,kBAyHsC;eAAiB,IAAA,CAAA;EAcnC,UAAA,SAAA,CAAA;IAaC,OAAA,EAAA,OAAA;EAAS;;UA3IjB,kBAAA;;ECnEJ,OAAA,CAAA,EAAA,GAAA,GAAA,IAAgB;;AAEP,cDsET,WAAA,CCtES;EAAZ,KAAA,EDuED,KCvEC;EACa,EAAA,EDuEjB,eCvEiB;EAUK,YAAA,EAAA,MAAA;EAoBA,YAAA,ED2CZ,MAAA,CAAO,OC3CK;EAAyB,QAAA,cAAA;EAAc,QAAA,WAAA;EAAM,QAAA,YAAA;wBDiDlD;WA8BV;2BAae,SAAA,CAAU;0BAYX;eAkCX;wBAQS,iBAAiB,iBAAiB;uBAcnC;wBAaC;;;;;cC9MZ,gBAAA;UACH;UACA,YAAY;uBACC;;EDClB,aAAA,EAAY,CAAA,OAAA,ECSW,eDLL,EAAA,QAAW,EAAA,GAAA,EAAA,GAAA,IAAA;EAK7B,aAAA,EAAA,CAAA,OAAgB,ECoBO,eDhBX,EAAA,MAAA,ECgBoC,MDhBpC,EAAA,IAAA,ECgBkD,MDhBlD,EAAA,GAAA,IAAA;AAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,209 @@
1
+ import { Vault } from "@iiif/helpers/vault";
2
+ import WebSocket, { WebSocketServer } from "ws";
3
+ import { v4 } from "uuid";
4
+ import { clearInterval, setInterval } from "timers";
5
+ import { createServer } from "http";
6
+
7
+ //#region \0@oxc-project+runtime@0.97.0/helpers/typeof.js
8
+ function _typeof(o) {
9
+ "@babel/helpers - typeof";
10
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
11
+ return typeof o$1;
12
+ } : function(o$1) {
13
+ return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
14
+ }, _typeof(o);
15
+ }
16
+
17
+ //#endregion
18
+ //#region \0@oxc-project+runtime@0.97.0/helpers/toPrimitive.js
19
+ function toPrimitive(t, r) {
20
+ if ("object" != _typeof(t) || !t) return t;
21
+ var e = t[Symbol.toPrimitive];
22
+ if (void 0 !== e) {
23
+ var i = e.call(t, r || "default");
24
+ if ("object" != _typeof(i)) return i;
25
+ throw new TypeError("@@toPrimitive must return a primitive value.");
26
+ }
27
+ return ("string" === r ? String : Number)(t);
28
+ }
29
+
30
+ //#endregion
31
+ //#region \0@oxc-project+runtime@0.97.0/helpers/toPropertyKey.js
32
+ function toPropertyKey(t) {
33
+ var i = toPrimitive(t, "string");
34
+ return "symbol" == _typeof(i) ? i : i + "";
35
+ }
36
+
37
+ //#endregion
38
+ //#region \0@oxc-project+runtime@0.97.0/helpers/defineProperty.js
39
+ function _defineProperty(e, r, t) {
40
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
41
+ value: t,
42
+ enumerable: !0,
43
+ configurable: !0,
44
+ writable: !0
45
+ }) : e[r] = t, e;
46
+ }
47
+
48
+ //#endregion
49
+ //#region src/server-vault.ts
50
+ const GenesisId = "@genesis";
51
+ var ServerVault = class {
52
+ constructor(options = {}) {
53
+ _defineProperty(this, "vault", void 0);
54
+ _defineProperty(this, "ws", void 0);
55
+ _defineProperty(this, "lastActionId", GenesisId);
56
+ _defineProperty(this, "pingInterval", void 0);
57
+ _defineProperty(this, "_handleMessage", /* @__PURE__ */ new Map());
58
+ _defineProperty(this, "_handleOpen", /* @__PURE__ */ new Map());
59
+ _defineProperty(this, "_handleClose", /* @__PURE__ */ new Map());
60
+ _defineProperty(this, "setupWebSocket", (socket) => {
61
+ socket.isAlive = true;
62
+ socket.on("pong", () => {
63
+ socket.isAlive = true;
64
+ });
65
+ socket.on("open", this.handleOpen(socket));
66
+ socket.on("message", this.handleMessage(socket));
67
+ socket.on("close", this.handleClose(socket));
68
+ socket.send(this.createMessage("init-response", { data: this.vault.getState() }));
69
+ });
70
+ _defineProperty(this, "handleMessage", (socket) => {
71
+ if (this._handleMessage.has(socket)) return this._handleMessage.get(socket);
72
+ const handler = (data, isBinary) => {
73
+ const parsed = JSON.parse(data.toString());
74
+ if (parsed._type === "init-request") socket.send(this.createMessage("init-response", { data: this.vault.getState() }));
75
+ if (parsed._type === "vault-action") {
76
+ try {
77
+ this.vault.dispatch(parsed.action);
78
+ } catch (e) {
79
+ socket.send(this.createMessage("vault-action-rejection", { action: parsed._id }));
80
+ return;
81
+ }
82
+ this.lastActionId = parsed._id;
83
+ this.rebroadcast(socket, data, parsed, isBinary);
84
+ }
85
+ };
86
+ this._handleMessage.set(socket, handler);
87
+ return handler;
88
+ });
89
+ _defineProperty(this, "send", (data) => {
90
+ this.ws.clients.forEach(function each(client) {
91
+ if (client.readyState === WebSocket.OPEN) client.send(data, { binary: true });
92
+ });
93
+ });
94
+ _defineProperty(this, "rebroadcast", (source, data, action, isBinary = true) => {
95
+ this.ws.clients.forEach((client) => {
96
+ if (client !== source && client.readyState === WebSocket.OPEN) client.send(data, { binary: isBinary });
97
+ else client.send(this.createMessage("vault-action-confirmation", { action: action._id }));
98
+ });
99
+ });
100
+ _defineProperty(this, "handleOpen", (socket) => {
101
+ if (this._handleOpen.has(socket)) return this._handleOpen.get(socket);
102
+ const handler = () => {};
103
+ this._handleOpen.set(socket, handler);
104
+ return handler;
105
+ });
106
+ _defineProperty(this, "handleClose", (socket) => {
107
+ if (this._handleClose.has(socket)) return this._handleClose.get(socket);
108
+ const handler = () => {};
109
+ this._handleClose.set(socket, handler);
110
+ return handler;
111
+ });
112
+ _defineProperty(this, "createMessage", (type, message) => {
113
+ return JSON.stringify({
114
+ _id: v4(),
115
+ _type: type,
116
+ _lastActionId: this.lastActionId,
117
+ ...message
118
+ });
119
+ });
120
+ this.vault = new Vault();
121
+ this.ws = new WebSocketServer({ noServer: true });
122
+ this.ws.on("connection", this.setupWebSocket);
123
+ this.pingInterval = setInterval(() => {
124
+ this.ws.clients.forEach((socket) => {
125
+ if (socket.isAlive === false) return socket.terminate();
126
+ socket.isAlive = false;
127
+ socket.ping();
128
+ });
129
+ }, options.pingTimeout || 3e4);
130
+ this.ws.on("close", () => {
131
+ clearInterval(this.pingInterval);
132
+ if (options.onClose) options.onClose();
133
+ });
134
+ this.ws.on("error", (err) => {});
135
+ }
136
+ async close() {
137
+ clearTimeout(this.pingInterval);
138
+ return new Promise((resolve, error) => {
139
+ this.ws.close((err) => {
140
+ if (err) error(err);
141
+ resolve();
142
+ });
143
+ });
144
+ }
145
+ };
146
+
147
+ //#endregion
148
+ //#region src/server.ts
149
+ var MultiVaultServer = class {
150
+ constructor(server) {
151
+ _defineProperty(this, "server", void 0);
152
+ _defineProperty(this, "vaults", /* @__PURE__ */ new Map());
153
+ _defineProperty(this, "handleRequest", (request, response) => {
154
+ if (request.url === "/vault") {
155
+ const vaults = Array.from(this.vaults.keys());
156
+ const json = JSON.stringify({ vaults });
157
+ response.writeHead(200, {
158
+ "Content-Length": Buffer.byteLength(json),
159
+ "Content-Type": "application/json"
160
+ });
161
+ response.write(json);
162
+ response.end();
163
+ return;
164
+ }
165
+ response.writeHead(404);
166
+ response.end();
167
+ });
168
+ _defineProperty(this, "handleUpgrade", (request, socket, head) => {
169
+ console.log("ws.url", request.url);
170
+ const pathname = request.url;
171
+ if (pathname && pathname.startsWith("/vault")) {
172
+ const vaultId = pathname.replace("/vault/", "");
173
+ let vault = this.vaults.get(vaultId);
174
+ if (!vault) {
175
+ const newVault = new ServerVault();
176
+ console.log("new vault", vaultId);
177
+ this.vaults.set(vaultId, newVault);
178
+ vault = newVault;
179
+ }
180
+ if (vault) {
181
+ const theVault = vault;
182
+ theVault.ws.handleUpgrade(request, socket, head, (ws) => {
183
+ console.log("new client", vaultId);
184
+ theVault.ws.emit("connection", ws, request);
185
+ theVault.ws.on("close", () => {
186
+ if (theVault.ws.clients.size === 0) {
187
+ console.log("destroying vault", vaultId);
188
+ this.vaults.delete(vaultId);
189
+ }
190
+ });
191
+ });
192
+ } else socket.destroy();
193
+ return;
194
+ }
195
+ socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
196
+ socket.destroy();
197
+ });
198
+ this.server = server || createServer();
199
+ this.server.on("upgrade", this.handleUpgrade);
200
+ this.server.on("request", this.handleRequest);
201
+ }
202
+ listen(port, hostname, backlog, listeningListener) {
203
+ this.server.listen(port, hostname, backlog, listeningListener);
204
+ }
205
+ };
206
+
207
+ //#endregion
208
+ export { MultiVaultServer, ServerVault };
209
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["parsed: ClientAction"],"sources":["../src/server-vault.ts","../src/server.ts"],"sourcesContent":["// Server vault.\nimport { AllActions, IIIFStore, Vault } from \"@iiif/helpers/vault\";\nimport { BatchAction } from \"@iiif/helpers/vault/actions\";\nimport { Collection, Manifest } from \"@iiif/presentation-3\";\nimport WebSocket, { RawData, WebSocketServer } from \"ws\";\nimport { v4 } from \"uuid\";\nimport { clearInterval, setInterval } from \"timers\";\n\ntype RemoteAction = {\n _id: string;\n _type: \"vault-action\";\n _lastActionId: string;\n action: AllActions | BatchAction;\n};\n\nconst GenesisId = \"@genesis\";\n\ntype ClientInitAction = {\n _id: string;\n _type: \"init-response\";\n _lastActionId: string;\n data: IIIFStore;\n};\n\ntype ClientInitRequestAction = {\n _type: \"init-request\";\n};\n\ntype RemoteActionConfirmation = {\n _id: string;\n _type: \"vault-action-confirmation\";\n _lastActionId: string;\n action: string;\n};\n\ntype RemoteActionRejection = {\n _id: string;\n _type: \"vault-action-rejection\";\n _lastActionId: string;\n action: string;\n};\n\ntype InitialiseWithResourceAction = {\n _id: string;\n _type: \"initialise-with-resource\";\n _lastActionId: string;\n resource: Collection | Manifest;\n};\n\ntype EmptyVaultResponse = {\n _id: string;\n _type: \"empty-vault-response\";\n _lastActionId: string;\n};\n\nexport type ClientAction = RemoteAction | ClientInitRequestAction | InitialiseWithResourceAction;\n\nexport type ServerAction =\n | RemoteAction\n | RemoteActionConfirmation\n | RemoteActionRejection\n | ClientInitAction\n | EmptyVaultResponse;\n\n// Extend ws module interface WebSocket.WebSocket with custom typescript property\ndeclare module \"ws\" {\n interface WebSocket {\n isAlive: boolean;\n }\n}\n\nexport interface ServerVaultOptions {\n pingTimeout?: number;\n onClose?: () => void;\n}\n\nexport class ServerVault {\n vault: Vault;\n ws: WebSocketServer;\n lastActionId: string = GenesisId;\n pingInterval: NodeJS.Timeout;\n\n private _handleMessage = new Map();\n private _handleOpen = new Map();\n private _handleClose = new Map();\n\n constructor(options: ServerVaultOptions = {}) {\n this.vault = new Vault();\n this.ws = new WebSocketServer({ noServer: true });\n\n this.ws.on(\"connection\", this.setupWebSocket);\n\n this.pingInterval = setInterval(() => {\n this.ws.clients.forEach((socket) => {\n if ((socket as any).isAlive === false) {\n return socket.terminate();\n }\n\n (socket as any).isAlive = false;\n socket.ping();\n });\n }, options.pingTimeout || 30000);\n\n this.ws.on(\"close\", () => {\n clearInterval(this.pingInterval);\n\n if (options.onClose) {\n options.onClose();\n }\n });\n\n this.ws.on(\"error\", (err) => {\n // @todo error handling.\n });\n }\n\n async close() {\n clearTimeout(this.pingInterval);\n\n return new Promise<void>((resolve, error) => {\n this.ws.close((err) => {\n if (err) {\n error(err);\n }\n resolve();\n });\n });\n }\n\n setupWebSocket = (socket: WebSocket.WebSocket) => {\n socket.isAlive = true;\n socket.on(\"pong\", () => {\n socket.isAlive = true;\n });\n socket.on(\"open\", this.handleOpen(socket));\n socket.on(\"message\", this.handleMessage(socket));\n socket.on(\"close\", this.handleClose(socket));\n // Send the initial state to the client.\n socket.send(this.createMessage(\"init-response\", { data: this.vault.getState() }));\n };\n\n handleMessage = (socket: WebSocket) => {\n if (this._handleMessage.has(socket)) {\n return this._handleMessage.get(socket);\n }\n const handler = (data: RawData, isBinary: boolean) => {\n const parsed: ClientAction = JSON.parse(data.toString());\n\n if (parsed._type === \"init-request\") {\n socket.send(this.createMessage(\"init-response\", { data: this.vault.getState() }));\n }\n\n if (parsed._type === \"vault-action\") {\n try {\n this.vault.dispatch(parsed.action);\n } catch (e) {\n // @todo error handling.\n socket.send(\n this.createMessage(\"vault-action-rejection\", {\n action: parsed._id,\n })\n );\n return;\n }\n\n this.lastActionId = parsed._id;\n this.rebroadcast(socket, data, parsed, isBinary);\n }\n };\n\n this._handleMessage.set(socket, handler);\n\n return handler;\n };\n\n send = (data: RawData) => {\n this.ws.clients.forEach(function each(client) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(data, { binary: true });\n }\n });\n };\n\n rebroadcast = (source: WebSocket, data: RawData, action: RemoteAction, isBinary = true) => {\n this.ws.clients.forEach((client) => {\n if (client !== source && client.readyState === WebSocket.OPEN) {\n client.send(data, { binary: isBinary });\n } else {\n client.send(\n this.createMessage(\"vault-action-confirmation\", {\n action: action._id,\n })\n );\n }\n });\n };\n\n handleOpen = (socket: WebSocket) => {\n if (this._handleOpen.has(socket)) {\n return this._handleOpen.get(socket);\n }\n const handler = () => {\n // Handle open.\n };\n\n this._handleOpen.set(socket, handler);\n\n return handler;\n };\n\n handleClose = (socket: WebSocket) => {\n if (this._handleClose.has(socket)) {\n return this._handleClose.get(socket);\n }\n const handler = () => {\n // Close handler.\n };\n\n this._handleClose.set(socket, handler);\n\n return handler;\n };\n\n createMessage = (type: string, message: any) => {\n return JSON.stringify({\n _id: v4(),\n _type: type,\n _lastActionId: this.lastActionId,\n ...message,\n });\n };\n}\n","import { createServer, IncomingMessage, Server } from \"http\";\nimport { Socket } from \"net\";\nimport { ServerVault } from \"./server-vault\";\n\nexport class MultiVaultServer {\n server: Server;\n vaults: Map<string, ServerVault> = new Map();\n constructor(server?: Server) {\n this.server = server || createServer();\n this.server.on(\"upgrade\", this.handleUpgrade);\n this.server.on(\"request\", this.handleRequest);\n }\n\n listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this.server.listen(port, hostname, backlog, listeningListener);\n }\n\n handleRequest = (request: IncomingMessage, response: any) => {\n if (request.url === \"/vault\") {\n // Need to respond with a JSON body with a list of available vaults.\n const vaults = Array.from(this.vaults.keys());\n const json = JSON.stringify({ vaults });\n\n response.writeHead(200, {\n \"Content-Length\": Buffer.byteLength(json),\n \"Content-Type\": \"application/json\",\n });\n response.write(json);\n response.end();\n return;\n }\n\n // If the pathname is not recognised, destroy the socket and send 404.\n response.writeHead(404);\n response.end();\n };\n\n handleUpgrade = (request: IncomingMessage, socket: Socket, head: Buffer) => {\n console.log(\"ws.url\", request.url);\n const pathname = request.url;\n\n // @todo some logic for handling the pathname. For now, just let any incoming be an ID.\n if (pathname && (pathname as string).startsWith(\"/vault\")) {\n // Get the vault ID from the URL.\n const vaultId = (pathname as string).replace(\"/vault/\", \"\");\n\n let vault = this.vaults.get(vaultId);\n\n // If no vault exists for this ID, create one.\n if (!vault) {\n const newVault = new ServerVault();\n console.log(\"new vault\", vaultId);\n this.vaults.set(vaultId, newVault);\n vault = newVault;\n }\n\n if (vault) {\n const theVault = vault;\n // If it exists, add the socket to the vault.\n theVault.ws.handleUpgrade(request, socket, head, (ws) => {\n console.log(\"new client\", vaultId);\n theVault.ws.emit(\"connection\", ws, request);\n theVault.ws.on(\"close\", () => {\n if (theVault.ws.clients.size === 0) {\n console.log(\"destroying vault\", vaultId);\n this.vaults.delete(vaultId);\n }\n });\n });\n } else {\n socket.destroy();\n }\n return;\n }\n\n // If the pathname is not recognised, destroy the socket and send 404.\n socket.write(\"HTTP/1.1 404 Not Found\\r\\n\\r\\n\");\n socket.destroy();\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@manifest-editor/server-vault",
3
- "version": "1.4.3",
3
+ "version": "2.0.1-next.0.2841cdd",
4
4
  "type": "module",
5
5
  "bugs": "https://github.com/digirati-co-uk/iiif-manifest-editor/issues",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/digirati-co-uk/iiif-manifest-editor.git",
8
+ "url": "git+https://github.com/digirati-co-uk/iiif-manifest-editor.git",
9
9
  "directory": "packages/server-vault"
10
10
  },
11
11
  "engines": {
@@ -23,32 +23,27 @@
23
23
  "timers"
24
24
  ],
25
25
  "main": "./dist/index.cjs",
26
- "module": "./dist/index.js",
27
- "types": "./dist/index.d.ts",
26
+ "module": "./dist/index.mjs",
27
+ "types": "./dist/index.d.cts",
28
28
  "files": [
29
29
  "dist"
30
30
  ],
31
31
  "exports": {
32
32
  ".": {
33
- "import": {
34
- "types": "./dist/index.d.ts",
35
- "default": "./dist/index.js"
36
- },
37
- "require": {
38
- "types": "./dist/index.d.cts",
39
- "default": "./dist/index.cjs"
40
- }
41
- }
33
+ "import": "./dist/index.mjs",
34
+ "require": "./dist/index.cjs"
35
+ },
36
+ "./package.json": "./package.json"
42
37
  },
43
38
  "scripts": {
44
- "build": "tsup src/index.ts",
45
- "dev": "tsup src/index.ts --watch",
39
+ "build": "tsdown src/index.ts",
40
+ "dev": "tsdown src/index.ts --watch",
46
41
  "lint": "publint",
47
42
  "typecheck": "tsc --noEmit",
48
- "prepack": "tsup src/index.ts"
43
+ "prepack": "tsdown src/index.ts"
49
44
  },
50
45
  "dependencies": {
51
- "@iiif/helpers": "^1.3.2",
46
+ "@iiif/helpers": "1.5.7",
52
47
  "@iiif/presentation-3": "^2.2.3",
53
48
  "uuid": "^9.0.1",
54
49
  "ws": "^8.16.0"
@@ -58,10 +53,10 @@
58
53
  "@types/node": "^20.11.24",
59
54
  "@types/uuid": "^9.0.8",
60
55
  "@types/ws": "8.5.10",
61
- "tsup": "^8.0.2"
56
+ "tsdown": "0.16.4"
62
57
  },
63
58
  "publishConfig": {
64
59
  "access": "public"
65
60
  },
66
- "gitHead": "830243a96a22a5d14b39e4c8a88cabb49a6f984a"
61
+ "gitHead": "2841cdd72fac56b862a9e901eb43cdcb0d9868d0"
67
62
  }
package/dist/index.d.ts DELETED
@@ -1,85 +0,0 @@
1
- import { Vault, AllActions, IIIFStore } from '@iiif/helpers/vault';
2
- import { BatchAction } from '@iiif/helpers/vault/actions';
3
- import { Collection, Manifest } from '@iiif/presentation-3';
4
- import WebSocket, { WebSocketServer, RawData } from 'ws';
5
- import { Server, IncomingMessage } from 'http';
6
- import { Socket } from 'net';
7
-
8
- type RemoteAction = {
9
- _id: string;
10
- _type: "vault-action";
11
- _lastActionId: string;
12
- action: AllActions | BatchAction;
13
- };
14
- type ClientInitAction = {
15
- _id: string;
16
- _type: "init-response";
17
- _lastActionId: string;
18
- data: IIIFStore;
19
- };
20
- type ClientInitRequestAction = {
21
- _type: "init-request";
22
- };
23
- type RemoteActionConfirmation = {
24
- _id: string;
25
- _type: "vault-action-confirmation";
26
- _lastActionId: string;
27
- action: string;
28
- };
29
- type RemoteActionRejection = {
30
- _id: string;
31
- _type: "vault-action-rejection";
32
- _lastActionId: string;
33
- action: string;
34
- };
35
- type InitialiseWithResourceAction = {
36
- _id: string;
37
- _type: "initialise-with-resource";
38
- _lastActionId: string;
39
- resource: Collection | Manifest;
40
- };
41
- type EmptyVaultResponse = {
42
- _id: string;
43
- _type: "empty-vault-response";
44
- _lastActionId: string;
45
- };
46
- type ClientAction = RemoteAction | ClientInitRequestAction | InitialiseWithResourceAction;
47
- type ServerAction = RemoteAction | RemoteActionConfirmation | RemoteActionRejection | ClientInitAction | EmptyVaultResponse;
48
- declare module "ws" {
49
- interface WebSocket {
50
- isAlive: boolean;
51
- }
52
- }
53
- interface ServerVaultOptions {
54
- pingTimeout?: number;
55
- onClose?: () => void;
56
- }
57
- declare class ServerVault {
58
- vault: Vault;
59
- ws: WebSocketServer;
60
- lastActionId: string;
61
- pingInterval: NodeJS.Timeout;
62
- private _handleMessage;
63
- private _handleOpen;
64
- private _handleClose;
65
- constructor(options?: ServerVaultOptions);
66
- close(): Promise<void>;
67
- setupWebSocket: (socket: WebSocket.WebSocket) => void;
68
- handleMessage: (socket: WebSocket) => any;
69
- send: (data: RawData) => void;
70
- rebroadcast: (source: WebSocket, data: RawData, action: RemoteAction, isBinary?: boolean) => void;
71
- handleOpen: (socket: WebSocket) => any;
72
- handleClose: (socket: WebSocket) => any;
73
- createMessage: (type: string, message: any) => string;
74
- }
75
-
76
- declare class MultiVaultServer {
77
- server: Server;
78
- vaults: Map<string, ServerVault>;
79
- constructor(server?: Server);
80
- listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
81
- handleRequest: (request: IncomingMessage, response: any) => void;
82
- handleUpgrade: (request: IncomingMessage, socket: Socket, head: Buffer) => void;
83
- }
84
-
85
- export { type ClientAction, MultiVaultServer, type ServerAction, ServerVault, type ServerVaultOptions };
package/dist/index.js DELETED
@@ -1,204 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
7
-
8
- // src/server-vault.ts
9
- import { Vault } from "@iiif/helpers/vault";
10
- import WebSocket, { WebSocketServer } from "ws";
11
- import { v4 } from "uuid";
12
- import { clearInterval, setInterval } from "timers";
13
- var GenesisId = "@genesis";
14
- var ServerVault = class {
15
- constructor(options = {}) {
16
- __publicField(this, "vault");
17
- __publicField(this, "ws");
18
- __publicField(this, "lastActionId", GenesisId);
19
- __publicField(this, "pingInterval");
20
- __publicField(this, "_handleMessage", /* @__PURE__ */ new Map());
21
- __publicField(this, "_handleOpen", /* @__PURE__ */ new Map());
22
- __publicField(this, "_handleClose", /* @__PURE__ */ new Map());
23
- __publicField(this, "setupWebSocket", (socket) => {
24
- socket.isAlive = true;
25
- socket.on("pong", () => {
26
- socket.isAlive = true;
27
- });
28
- socket.on("open", this.handleOpen(socket));
29
- socket.on("message", this.handleMessage(socket));
30
- socket.on("close", this.handleClose(socket));
31
- socket.send(this.createMessage("init-response", { data: this.vault.getState() }));
32
- });
33
- __publicField(this, "handleMessage", (socket) => {
34
- if (this._handleMessage.has(socket)) {
35
- return this._handleMessage.get(socket);
36
- }
37
- const handler = (data, isBinary) => {
38
- const parsed = JSON.parse(data.toString());
39
- if (parsed._type === "init-request") {
40
- socket.send(this.createMessage("init-response", { data: this.vault.getState() }));
41
- }
42
- if (parsed._type === "vault-action") {
43
- try {
44
- this.vault.dispatch(parsed.action);
45
- } catch (e) {
46
- socket.send(
47
- this.createMessage("vault-action-rejection", {
48
- action: parsed._id
49
- })
50
- );
51
- return;
52
- }
53
- this.lastActionId = parsed._id;
54
- this.rebroadcast(socket, data, parsed, isBinary);
55
- }
56
- };
57
- this._handleMessage.set(socket, handler);
58
- return handler;
59
- });
60
- __publicField(this, "send", (data) => {
61
- this.ws.clients.forEach(function each(client) {
62
- if (client.readyState === WebSocket.OPEN) {
63
- client.send(data, { binary: true });
64
- }
65
- });
66
- });
67
- __publicField(this, "rebroadcast", (source, data, action, isBinary = true) => {
68
- this.ws.clients.forEach((client) => {
69
- if (client !== source && client.readyState === WebSocket.OPEN) {
70
- client.send(data, { binary: isBinary });
71
- } else {
72
- client.send(
73
- this.createMessage("vault-action-confirmation", {
74
- action: action._id
75
- })
76
- );
77
- }
78
- });
79
- });
80
- __publicField(this, "handleOpen", (socket) => {
81
- if (this._handleOpen.has(socket)) {
82
- return this._handleOpen.get(socket);
83
- }
84
- const handler = () => {
85
- };
86
- this._handleOpen.set(socket, handler);
87
- return handler;
88
- });
89
- __publicField(this, "handleClose", (socket) => {
90
- if (this._handleClose.has(socket)) {
91
- return this._handleClose.get(socket);
92
- }
93
- const handler = () => {
94
- };
95
- this._handleClose.set(socket, handler);
96
- return handler;
97
- });
98
- __publicField(this, "createMessage", (type, message) => {
99
- return JSON.stringify({
100
- _id: v4(),
101
- _type: type,
102
- _lastActionId: this.lastActionId,
103
- ...message
104
- });
105
- });
106
- this.vault = new Vault();
107
- this.ws = new WebSocketServer({ noServer: true });
108
- this.ws.on("connection", this.setupWebSocket);
109
- this.pingInterval = setInterval(() => {
110
- this.ws.clients.forEach((socket) => {
111
- if (socket.isAlive === false) {
112
- return socket.terminate();
113
- }
114
- socket.isAlive = false;
115
- socket.ping();
116
- });
117
- }, options.pingTimeout || 3e4);
118
- this.ws.on("close", () => {
119
- clearInterval(this.pingInterval);
120
- if (options.onClose) {
121
- options.onClose();
122
- }
123
- });
124
- this.ws.on("error", (err) => {
125
- });
126
- }
127
- async close() {
128
- clearTimeout(this.pingInterval);
129
- return new Promise((resolve, error) => {
130
- this.ws.close((err) => {
131
- if (err) {
132
- error(err);
133
- }
134
- resolve();
135
- });
136
- });
137
- }
138
- };
139
-
140
- // src/server.ts
141
- import { createServer } from "http";
142
- var MultiVaultServer = class {
143
- constructor(server) {
144
- __publicField(this, "server");
145
- __publicField(this, "vaults", /* @__PURE__ */ new Map());
146
- __publicField(this, "handleRequest", (request, response) => {
147
- if (request.url === "/vault") {
148
- const vaults = Array.from(this.vaults.keys());
149
- const json = JSON.stringify({ vaults });
150
- response.writeHead(200, {
151
- "Content-Length": Buffer.byteLength(json),
152
- "Content-Type": "application/json"
153
- });
154
- response.write(json);
155
- response.end();
156
- return;
157
- }
158
- response.writeHead(404);
159
- response.end();
160
- });
161
- __publicField(this, "handleUpgrade", (request, socket, head) => {
162
- console.log("ws.url", request.url);
163
- const pathname = request.url;
164
- if (pathname && pathname.startsWith("/vault")) {
165
- const vaultId = pathname.replace("/vault/", "");
166
- let vault = this.vaults.get(vaultId);
167
- if (!vault) {
168
- const newVault = new ServerVault();
169
- console.log("new vault", vaultId);
170
- this.vaults.set(vaultId, newVault);
171
- vault = newVault;
172
- }
173
- if (vault) {
174
- const theVault = vault;
175
- theVault.ws.handleUpgrade(request, socket, head, (ws) => {
176
- console.log("new client", vaultId);
177
- theVault.ws.emit("connection", ws, request);
178
- theVault.ws.on("close", () => {
179
- if (theVault.ws.clients.size === 0) {
180
- console.log("destroying vault", vaultId);
181
- this.vaults.delete(vaultId);
182
- }
183
- });
184
- });
185
- } else {
186
- socket.destroy();
187
- }
188
- return;
189
- }
190
- socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
191
- socket.destroy();
192
- });
193
- this.server = server || createServer();
194
- this.server.on("upgrade", this.handleUpgrade);
195
- this.server.on("request", this.handleRequest);
196
- }
197
- listen(port, hostname, backlog, listeningListener) {
198
- this.server.listen(port, hostname, backlog, listeningListener);
199
- }
200
- };
201
- export {
202
- MultiVaultServer,
203
- ServerVault
204
- };