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 CHANGED
@@ -1,272 +1,120 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
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: function () { },
6
+ start: () => { },
69
7
  };
70
- var _loop_1 = function (functionName) {
71
- instance[functionName] = (function (implementation) {
8
+ for (const functionName in procedures) {
9
+ instance[functionName] = ((implementation) => {
72
10
  if (!instance.procedures[functionName]) {
73
- throw new Error("No procedure found for function name: ".concat(functionName));
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
- var PayloadSchema = arktype_1.type.or.apply(arktype_1.type, Object.entries(procedures).map(function (_a) {
82
- var functionName = _a[0], input = _a[1].input;
83
- return ({
84
- functionName: (0, arktype_1.type)("\"".concat(functionName, "\"")),
85
- requestId: (0, arktype_1.type)("string >= 1"),
86
- input: input,
87
- });
88
- }));
89
- instance.start = function (self) {
90
- var postMessage = function (data) { return __awaiter(_this, void 0, void 0, function () {
91
- return __generator(this, function (_a) {
92
- switch (_a.label) {
93
- case 0:
94
- if (!worker) return [3 /*break*/, 1];
95
- self.postMessage(data);
96
- return [3 /*break*/, 3];
97
- case 1: return [4 /*yield*/, self.clients.matchAll().then(function (clients) {
98
- clients.forEach(function (client) { return client.postMessage(data); });
99
- })];
100
- case 2:
101
- _a.sent();
102
- _a.label = 3;
103
- case 3: return [2 /*return*/];
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
- self.addEventListener("message", function (event) { return __awaiter(_this, void 0, void 0, function () {
108
- var _a, functionName, requestId, input, postError, implementation;
109
- var _this = this;
110
- return __generator(this, function (_b) {
111
- switch (_b.label) {
112
- case 0:
113
- _a = PayloadSchema.assert(event.data), functionName = _a.functionName, requestId = _a.requestId, input = _a.input;
114
- postError = function (error) { return __awaiter(_this, void 0, void 0, function () {
115
- return __generator(this, function (_a) {
116
- return [2 /*return*/, postMessage({
117
- functionName: functionName,
118
- requestId: requestId,
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
- var pendingRequests = new Map();
174
- var _clientListenerStarted = false;
175
- function startClientListener(worker) {
176
- return __awaiter(this, void 0, void 0, function () {
177
- var sw, w;
178
- return __generator(this, function (_a) {
179
- switch (_a.label) {
180
- case 0:
181
- if (_clientListenerStarted)
182
- return [2 /*return*/];
183
- if (!!worker) return [3 /*break*/, 2];
184
- return [4 /*yield*/, navigator.serviceWorker.ready];
185
- case 1:
186
- sw = _a.sent();
187
- if (!(sw === null || sw === void 0 ? void 0 : sw.active)) {
188
- throw new Error("[SWARPC Client] Service Worker is not active");
189
- }
190
- if (!navigator.serviceWorker.controller) {
191
- console.warn("[SWARPC Client] Service Worker is not controlling the page");
192
- }
193
- _a.label = 2;
194
- case 2:
195
- w = worker !== null && worker !== void 0 ? worker : navigator.serviceWorker;
196
- w.addEventListener("message", function (event) {
197
- var _a = event.data || {}, functionName = _a.functionName, requestId = _a.requestId, data = __rest(_a, ["functionName", "requestId"]);
198
- if (!requestId) {
199
- throw new Error("[SWARPC Client] Message received without requestId");
200
- }
201
- var handlers = pendingRequests.get(requestId);
202
- if (!handlers) {
203
- throw new Error("[SWARPC Client] ".concat(requestId, " has no active request handlers"));
204
- }
205
- if ("error" in data) {
206
- handlers.reject(new Error(data.error.message));
207
- pendingRequests.delete(requestId);
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, _a) {
224
- var _this = this;
225
- var _b = _a === void 0 ? {} : _a, worker = _b.worker;
226
- var instance = { procedures: procedures };
227
- var _loop_2 = function (functionName) {
228
- instance[functionName] = (function (input_1) {
229
- var args_1 = [];
230
- for (var _i = 1; _i < arguments.length; _i++) {
231
- args_1[_i - 1] = arguments[_i];
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 __awaiter(_this, __spreadArray([input_1], args_1, true), void 0, function (input, onProgress) {
234
- var w, _a;
235
- if (onProgress === void 0) { onProgress = function () { }; }
236
- return __generator(this, function (_b) {
237
- switch (_b.label) {
238
- case 0:
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swarpc",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Full type-safe RPC library for service worker -- move things off of the UI thread with ease!",
5
5
  "keywords": [
6
6
  "service-workers",
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: MessageEvent) => {
116
- const { functionName, requestId, ...data } = event.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