swarpc 0.2.1 → 0.2.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.
- package/dist/swarpc.js +97 -249
- package/dist/types.js +1 -2
- package/package.json +1 -1
- package/src/swarpc.ts +7 -9
package/dist/swarpc.js
CHANGED
|
@@ -1,272 +1,120 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
39
|
-
var t = {};
|
|
40
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
41
|
-
t[p] = s[p];
|
|
42
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
43
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
44
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
45
|
-
t[p[i]] = s[p[i]];
|
|
46
|
-
}
|
|
47
|
-
return t;
|
|
48
|
-
};
|
|
49
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
50
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
51
|
-
if (ar || !(i in from)) {
|
|
52
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
53
|
-
ar[i] = from[i];
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
57
|
-
};
|
|
58
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
-
exports.Server = Server;
|
|
60
|
-
exports.Client = Client;
|
|
61
|
-
var arktype_1 = require("arktype");
|
|
62
|
-
function Server(procedures, _a) {
|
|
63
|
-
var _this = this;
|
|
64
|
-
var _b = _a === void 0 ? {} : _a, worker = _b.worker;
|
|
65
|
-
var instance = {
|
|
66
|
-
procedures: procedures,
|
|
1
|
+
import { type } from "arktype";
|
|
2
|
+
export function Server(procedures, { worker } = {}) {
|
|
3
|
+
const instance = {
|
|
4
|
+
procedures,
|
|
67
5
|
implementations: {},
|
|
68
|
-
start:
|
|
6
|
+
start: () => { },
|
|
69
7
|
};
|
|
70
|
-
|
|
71
|
-
instance[functionName] = (
|
|
8
|
+
for (const functionName in procedures) {
|
|
9
|
+
instance[functionName] = ((implementation) => {
|
|
72
10
|
if (!instance.procedures[functionName]) {
|
|
73
|
-
throw new Error(
|
|
11
|
+
throw new Error(`No procedure found for function name: ${functionName}`);
|
|
74
12
|
}
|
|
75
13
|
instance.implementations[functionName] = implementation;
|
|
76
14
|
});
|
|
77
|
-
};
|
|
78
|
-
for (var functionName in procedures) {
|
|
79
|
-
_loop_1(functionName);
|
|
80
15
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
16
|
+
const PayloadSchema = type.or(...Object.entries(procedures).map(([functionName, { input }]) => ({
|
|
17
|
+
functionName: type(`"${functionName}"`),
|
|
18
|
+
requestId: type("string >= 1"),
|
|
19
|
+
input,
|
|
20
|
+
})));
|
|
21
|
+
instance.start = (self) => {
|
|
22
|
+
const postMessage = async (data) => {
|
|
23
|
+
if (worker) {
|
|
24
|
+
self.postMessage(data);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
await self.clients.matchAll().then((clients) => {
|
|
28
|
+
clients.forEach((client) => client.postMessage(data));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
self.addEventListener("message", async (event) => {
|
|
33
|
+
const { functionName, requestId, input } = PayloadSchema.assert(event.data);
|
|
34
|
+
const postError = async (error) => postMessage({
|
|
35
|
+
functionName,
|
|
36
|
+
requestId,
|
|
37
|
+
error: {
|
|
38
|
+
message: "message" in error ? error.message : String(error),
|
|
39
|
+
},
|
|
105
40
|
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
error: {
|
|
120
|
-
message: "message" in error ? error.message : String(error),
|
|
121
|
-
},
|
|
122
|
-
})];
|
|
123
|
-
});
|
|
124
|
-
}); };
|
|
125
|
-
implementation = instance.implementations[functionName];
|
|
126
|
-
if (!!implementation) return [3 /*break*/, 2];
|
|
127
|
-
return [4 /*yield*/, postError("No implementation found")];
|
|
128
|
-
case 1:
|
|
129
|
-
_b.sent();
|
|
130
|
-
return [2 /*return*/];
|
|
131
|
-
case 2: return [4 /*yield*/, implementation(input, function (progress) { return __awaiter(_this, void 0, void 0, function () {
|
|
132
|
-
return __generator(this, function (_a) {
|
|
133
|
-
switch (_a.label) {
|
|
134
|
-
case 0: return [4 /*yield*/, postMessage({ functionName: functionName, requestId: requestId, progress: progress })];
|
|
135
|
-
case 1:
|
|
136
|
-
_a.sent();
|
|
137
|
-
return [2 /*return*/];
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
}); })
|
|
141
|
-
.catch(function (error) { return __awaiter(_this, void 0, void 0, function () {
|
|
142
|
-
return __generator(this, function (_a) {
|
|
143
|
-
switch (_a.label) {
|
|
144
|
-
case 0: return [4 /*yield*/, postError(error)];
|
|
145
|
-
case 1:
|
|
146
|
-
_a.sent();
|
|
147
|
-
return [2 /*return*/];
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
}); })
|
|
151
|
-
.then(function (result) { return __awaiter(_this, void 0, void 0, function () {
|
|
152
|
-
return __generator(this, function (_a) {
|
|
153
|
-
switch (_a.label) {
|
|
154
|
-
case 0: return [4 /*yield*/, postMessage({ functionName: functionName, requestId: requestId, result: result })];
|
|
155
|
-
case 1:
|
|
156
|
-
_a.sent();
|
|
157
|
-
return [2 /*return*/];
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
}); })];
|
|
161
|
-
case 3:
|
|
162
|
-
_b.sent();
|
|
163
|
-
return [2 /*return*/];
|
|
164
|
-
}
|
|
41
|
+
const implementation = instance.implementations[functionName];
|
|
42
|
+
if (!implementation) {
|
|
43
|
+
await postError("No implementation found");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
await implementation(input, async (progress) => {
|
|
47
|
+
await postMessage({ functionName, requestId, progress });
|
|
48
|
+
})
|
|
49
|
+
.catch(async (error) => {
|
|
50
|
+
await postError(error);
|
|
51
|
+
})
|
|
52
|
+
.then(async (result) => {
|
|
53
|
+
await postMessage({ functionName, requestId, result });
|
|
165
54
|
});
|
|
166
|
-
});
|
|
55
|
+
});
|
|
167
56
|
};
|
|
168
57
|
return instance;
|
|
169
58
|
}
|
|
170
59
|
function generateRequestId() {
|
|
171
60
|
return Math.random().toString(36).substring(2, 15);
|
|
172
61
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
function startClientListener(worker) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
else if ("progress" in data) {
|
|
210
|
-
handlers.onProgress(data.progress);
|
|
211
|
-
}
|
|
212
|
-
else if ("result" in data) {
|
|
213
|
-
handlers.resolve(data.result);
|
|
214
|
-
pendingRequests.delete(requestId);
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
_clientListenerStarted = true;
|
|
218
|
-
return [2 /*return*/];
|
|
219
|
-
}
|
|
220
|
-
});
|
|
62
|
+
const pendingRequests = new Map();
|
|
63
|
+
let _clientListenerStarted = false;
|
|
64
|
+
async function startClientListener(worker) {
|
|
65
|
+
if (_clientListenerStarted)
|
|
66
|
+
return;
|
|
67
|
+
if (!worker) {
|
|
68
|
+
const sw = await navigator.serviceWorker.ready;
|
|
69
|
+
if (!sw?.active) {
|
|
70
|
+
throw new Error("[SWARPC Client] Service Worker is not active");
|
|
71
|
+
}
|
|
72
|
+
if (!navigator.serviceWorker.controller) {
|
|
73
|
+
console.warn("[SWARPC Client] Service Worker is not controlling the page");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const w = worker ?? navigator.serviceWorker;
|
|
77
|
+
w.addEventListener("message", (event) => {
|
|
78
|
+
const { functionName, requestId, ...data } = event.data || {};
|
|
79
|
+
if (!requestId) {
|
|
80
|
+
throw new Error("[SWARPC Client] Message received without requestId");
|
|
81
|
+
}
|
|
82
|
+
const handlers = pendingRequests.get(requestId);
|
|
83
|
+
if (!handlers) {
|
|
84
|
+
throw new Error(`[SWARPC Client] ${requestId} has no active request handlers`);
|
|
85
|
+
}
|
|
86
|
+
if ("error" in data) {
|
|
87
|
+
handlers.reject(new Error(data.error.message));
|
|
88
|
+
pendingRequests.delete(requestId);
|
|
89
|
+
}
|
|
90
|
+
else if ("progress" in data) {
|
|
91
|
+
handlers.onProgress(data.progress);
|
|
92
|
+
}
|
|
93
|
+
else if ("result" in data) {
|
|
94
|
+
handlers.resolve(data.result);
|
|
95
|
+
pendingRequests.delete(requestId);
|
|
96
|
+
}
|
|
221
97
|
});
|
|
98
|
+
_clientListenerStarted = true;
|
|
222
99
|
}
|
|
223
|
-
function Client(procedures,
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
100
|
+
export function Client(procedures, { worker } = {}) {
|
|
101
|
+
const instance = { procedures };
|
|
102
|
+
for (const functionName of Object.keys(procedures)) {
|
|
103
|
+
instance[functionName] = (async (input, onProgress = () => { }) => {
|
|
104
|
+
procedures[functionName].input.assert(input);
|
|
105
|
+
await startClientListener(worker);
|
|
106
|
+
const w = worker ?? (await navigator.serviceWorker.ready.then((r) => r.active));
|
|
107
|
+
if (!w) {
|
|
108
|
+
throw new Error("[SWARPC Client] No active service worker found");
|
|
232
109
|
}
|
|
233
|
-
return
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
procedures[functionName].input.assert(input);
|
|
240
|
-
return [4 /*yield*/, startClientListener(worker)];
|
|
241
|
-
case 1:
|
|
242
|
-
_b.sent();
|
|
243
|
-
if (!(worker !== null && worker !== void 0)) return [3 /*break*/, 2];
|
|
244
|
-
_a = worker;
|
|
245
|
-
return [3 /*break*/, 4];
|
|
246
|
-
case 2: return [4 /*yield*/, navigator.serviceWorker.ready.then(function (r) { return r.active; })];
|
|
247
|
-
case 3:
|
|
248
|
-
_a = (_b.sent());
|
|
249
|
-
_b.label = 4;
|
|
250
|
-
case 4:
|
|
251
|
-
w = _a;
|
|
252
|
-
if (!w) {
|
|
253
|
-
throw new Error("[SWARPC Client] No active service worker found");
|
|
254
|
-
}
|
|
255
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
256
|
-
if (!worker && !navigator.serviceWorker.controller)
|
|
257
|
-
console.warn("[SWARPC Client] Service Worker is not controlling the page");
|
|
258
|
-
var requestId = generateRequestId();
|
|
259
|
-
pendingRequests.set(requestId, { resolve: resolve, onProgress: onProgress, reject: reject });
|
|
260
|
-
w.postMessage({ functionName: functionName, input: input, requestId: requestId });
|
|
261
|
-
})];
|
|
262
|
-
}
|
|
263
|
-
});
|
|
110
|
+
return new Promise((resolve, reject) => {
|
|
111
|
+
if (!worker && !navigator.serviceWorker.controller)
|
|
112
|
+
console.warn("[SWARPC Client] Service Worker is not controlling the page");
|
|
113
|
+
const requestId = generateRequestId();
|
|
114
|
+
pendingRequests.set(requestId, { resolve, onProgress, reject });
|
|
115
|
+
w.postMessage({ functionName, input, requestId });
|
|
264
116
|
});
|
|
265
117
|
});
|
|
266
|
-
};
|
|
267
|
-
for (var _i = 0, _c = Object.keys(procedures); _i < _c.length; _i++) {
|
|
268
|
-
var functionName = _c[_i];
|
|
269
|
-
_loop_2(functionName);
|
|
270
118
|
}
|
|
271
119
|
return instance;
|
|
272
120
|
}
|
package/dist/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/package.json
CHANGED
package/src/swarpc.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { type } from "arktype"
|
|
2
|
-
import type {
|
|
3
|
-
ProceduresMap,
|
|
4
|
-
SwarpcClient,
|
|
5
|
-
SwarpcServer,
|
|
6
|
-
ProcedureImplementation,
|
|
7
|
-
} from "./types"
|
|
2
|
+
import type { ProceduresMap, SwarpcClient, SwarpcServer } from "./types.js"
|
|
8
3
|
|
|
9
4
|
export function Server<Procedures extends ProceduresMap>(
|
|
10
5
|
procedures: Procedures,
|
|
@@ -112,11 +107,14 @@ async function startClientListener(worker?: Worker) {
|
|
|
112
107
|
}
|
|
113
108
|
|
|
114
109
|
const w = worker ?? navigator.serviceWorker
|
|
115
|
-
w.addEventListener("message", (event
|
|
116
|
-
const { functionName, requestId, ...data } =
|
|
110
|
+
w.addEventListener("message", (event) => {
|
|
111
|
+
const { functionName, requestId, ...data } =
|
|
112
|
+
(event as MessageEvent).data || {}
|
|
113
|
+
|
|
117
114
|
if (!requestId) {
|
|
118
115
|
throw new Error("[SWARPC Client] Message received without requestId")
|
|
119
116
|
}
|
|
117
|
+
|
|
120
118
|
const handlers = pendingRequests.get(requestId)
|
|
121
119
|
if (!handlers) {
|
|
122
120
|
throw new Error(
|
|
@@ -147,7 +145,7 @@ export function Client<Procedures extends ProceduresMap>(
|
|
|
147
145
|
for (const functionName of Object.keys(procedures) as Array<
|
|
148
146
|
keyof Procedures
|
|
149
147
|
>) {
|
|
150
|
-
instance[functionName] = (async (input, onProgress = () => {}) => {
|
|
148
|
+
instance[functionName] = (async (input: unknown, onProgress = () => {}) => {
|
|
151
149
|
procedures[functionName].input.assert(input)
|
|
152
150
|
await startClientListener(worker)
|
|
153
151
|
|