@wix/himalaya-cli 0.1450.0 → 0.1452.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.
@@ -1,157 +1,289 @@
1
- // ../../core/sdk/webview-page/src/index.ts
2
- var pending = /* @__PURE__ */ new Map();
3
- var installedOn;
4
- var nextId = 1;
5
- function workerBridge() {
6
- const bridge = globalThis.HimalayaWorker;
7
- if (!bridge || typeof bridge.post !== "function" || typeof bridge.onMessage !== "function") {
8
- throw new Error(
9
- "@himalaya/webview-page: this page is not inside a worker-backed Himalaya WebView."
10
- );
11
- }
12
- if (installedOn !== bridge) {
13
- bridge.onMessage(receive);
14
- installedOn = bridge;
15
- }
16
- return bridge;
17
- }
18
- function isResponse(value) {
19
- if (!value || typeof value !== "object") return false;
20
- const r = value;
21
- return r.v === 1 && typeof r.id === "string" && typeof r.ok === "boolean";
1
+ // ../../core/sdk/webview-page/src/client.ts
2
+ var TIMEOUT_PREFIX = "Himalaya capability call timed out";
3
+ function pageError(error) {
4
+ const out = new Error(error?.message ?? "Himalaya capability call failed");
5
+ if (error?.code) Object.assign(out, { code: error.code });
6
+ return out;
22
7
  }
23
- function receive(message) {
24
- if (!isResponse(message)) return;
25
- const call2 = pending.get(message.id);
26
- if (!call2) return;
27
- pending.delete(message.id);
28
- clearTimeout(call2.timeout);
29
- if (message.ok) {
30
- call2.resolve(message.result);
31
- return;
32
- }
33
- const error = new Error(message.error?.message ?? "Himalaya capability call failed");
34
- if (message.error?.code) Object.assign(error, { code: message.error.code });
35
- call2.reject(error);
36
- }
37
- function call(capability, method, args = [], timeoutMs = 3e4) {
38
- const bridge = workerBridge();
39
- const id = `page-${Date.now().toString(36)}-${nextId++}`;
40
- const request = { v: 1, id, capability, method, args };
41
- return new Promise((resolve, reject) => {
42
- const timeout = setTimeout(() => {
43
- pending.delete(id);
44
- reject(new Error(`Himalaya capability call timed out: ${capability}.${method}`));
45
- }, timeoutMs);
46
- pending.set(id, { resolve, reject, timeout });
47
- if (!bridge.post(request)) {
48
- clearTimeout(timeout);
49
- pending.delete(id);
50
- reject(new Error("@himalaya/webview-page: the native page-to-worker bridge refused the request."));
8
+ function createPageClient(getBridge) {
9
+ const pending = /* @__PURE__ */ new Map();
10
+ const abandoned = /* @__PURE__ */ new Set();
11
+ const streams = /* @__PURE__ */ new Map();
12
+ const listeners = /* @__PURE__ */ new Map();
13
+ let installedOn;
14
+ let nextId = 1;
15
+ const clientTag = Math.random().toString(36).slice(2, 10) || "0";
16
+ function workerBridge() {
17
+ const bridge = getBridge();
18
+ if (!bridge || typeof bridge.post !== "function" || typeof bridge.onMessage !== "function") {
19
+ throw new Error(
20
+ "@himalaya/webview-page: this page is not inside a worker-backed Himalaya WebView."
21
+ );
51
22
  }
52
- });
53
- }
54
- var manifest;
55
- function currentBridge() {
56
- try {
57
- return workerBridge();
58
- } catch {
59
- return void 0;
23
+ if (installedOn !== bridge) {
24
+ bridge.onMessage(receive);
25
+ installedOn = bridge;
26
+ }
27
+ return bridge;
60
28
  }
61
- }
62
- function timedOut(error) {
63
- return error instanceof Error && error.message.startsWith("Himalaya capability call timed out");
64
- }
65
- var asking;
66
- function askShared(target, budget) {
67
- const until = Date.now() + budget;
68
- if (asking?.on === target) {
69
- asking.until = Math.max(asking.until, until);
70
- return asking.answer;
71
- }
72
- const state = { on: target, until, answer: Promise.resolve(null) };
73
- asking = state;
74
- state.answer = new Promise((resolve) => {
75
- let done = false;
76
- const finish = (list) => {
77
- if (done) return;
78
- done = true;
79
- clearInterval(again);
80
- if (asking === state) asking = void 0;
81
- if (list) manifest = { on: target, list };
82
- resolve(list);
83
- };
84
- const ask = () => {
85
- if (done) return;
86
- const left = state.until - Date.now();
87
- if (left <= 0 || currentBridge() !== target) return finish(null);
88
- call("himalaya", "capabilities", [], Math.max(1, Math.min(2e3, left))).then(
89
- (reply) => finish(reply?.capabilities ?? null),
90
- // A timed-out question is not an answer; the deadline decides. Anything else is final.
91
- (error) => {
92
- if (!timedOut(error)) finish(null);
29
+ function receive(message) {
30
+ if (!message || typeof message !== "object" || message.v !== 1) return;
31
+ const m = message;
32
+ if (typeof m.id === "string" && typeof m.ok === "boolean") return respond(m);
33
+ if (typeof m.ev === "string" && typeof m.ns === "string") return emit(m);
34
+ if (typeof m.sid === "string") return feed(m);
35
+ }
36
+ function respond(message) {
37
+ const call3 = pending.get(message.id);
38
+ if (!call3) {
39
+ if (abandoned.delete(message.id) && message.ok && message.stream === true) cancelStream(message.id);
40
+ return;
41
+ }
42
+ pending.delete(message.id);
43
+ clearTimeout(call3.timeout);
44
+ if (!message.ok) return call3.reject(pageError(message.error));
45
+ if (message.stream === true) return call3.resolve(openStream(message.id));
46
+ call3.resolve(message.result);
47
+ }
48
+ function emit(event) {
49
+ const handlers = listeners.get(event.ns)?.get(event.ev);
50
+ if (!handlers) return;
51
+ for (const handler of [...handlers]) {
52
+ try {
53
+ handler(event.data);
54
+ } catch {
55
+ }
56
+ }
57
+ }
58
+ function feed(envelope) {
59
+ const state = streams.get(envelope.sid);
60
+ if (!state) return;
61
+ if (!("chunk" in envelope) && !("end" in envelope && envelope.end === true) && !("error" in envelope && envelope.error)) return;
62
+ if ("chunk" in envelope) {
63
+ const waiter = state.waiters.shift();
64
+ if (waiter) waiter.resolve({ value: envelope.chunk, done: false });
65
+ else state.queue.push(envelope.chunk);
66
+ return;
67
+ }
68
+ streams.delete(envelope.sid);
69
+ if ("error" in envelope && envelope.error) {
70
+ state.error = pageError(envelope.error);
71
+ if (state.waiters.length > 0) {
72
+ for (const waiter of state.waiters.splice(0)) waiter.reject(state.error);
73
+ state.error = void 0;
74
+ state.done = true;
75
+ }
76
+ } else if ("end" in envelope && envelope.end === true) {
77
+ state.done = true;
78
+ for (const waiter of state.waiters.splice(0)) waiter.resolve({ value: void 0, done: true });
79
+ }
80
+ }
81
+ function cancelStream(sid) {
82
+ try {
83
+ installedOn?.post({ v: 1, sys: "cancel", sid });
84
+ } catch {
85
+ }
86
+ }
87
+ function openStream(sid) {
88
+ const state = { queue: [], waiters: [], done: false, error: void 0 };
89
+ streams.set(sid, state);
90
+ const iterator = {
91
+ next() {
92
+ if (state.queue.length > 0) return Promise.resolve({ value: state.queue.shift(), done: false });
93
+ if (state.error) {
94
+ const error = state.error;
95
+ state.error = void 0;
96
+ state.done = true;
97
+ return Promise.reject(error);
93
98
  }
94
- );
99
+ if (state.done) return Promise.resolve({ value: void 0, done: true });
100
+ return new Promise((resolve, reject) => state.waiters.push({ resolve, reject }));
101
+ },
102
+ return() {
103
+ if (streams.get(sid) === state) {
104
+ streams.delete(sid);
105
+ cancelStream(sid);
106
+ }
107
+ state.done = true;
108
+ state.queue.length = 0;
109
+ for (const waiter of state.waiters.splice(0)) waiter.resolve({ value: void 0, done: true });
110
+ return Promise.resolve({ value: void 0, done: true });
111
+ }
95
112
  };
96
- const again = setInterval(ask, 500);
97
- ask();
98
- });
99
- return state.answer;
100
- }
101
- async function enabledCapabilities(timeoutMs = 3e3) {
102
- const bridge = currentBridge();
103
- if (!bridge) return null;
104
- if (manifest?.on === bridge) return manifest.list;
105
- if (!(timeoutMs > 0)) return null;
106
- const budget = Math.min(timeoutMs, 2147483647);
107
- const answer = askShared(bridge, budget);
108
- return new Promise((resolve) => {
109
- const stop = setTimeout(() => resolve(manifest?.on === bridge ? manifest.list : null), budget);
110
- void answer.then((list) => {
111
- clearTimeout(stop);
112
- resolve(list);
113
+ return { [Symbol.asyncIterator]: () => iterator };
114
+ }
115
+ function call2(capability, method, args = [], timeoutMs = 3e4) {
116
+ const bridge = workerBridge();
117
+ const id = `page-${Date.now().toString(36)}-${clientTag}-${nextId++}`;
118
+ const request = { v: 1, id, capability, method, args };
119
+ return new Promise((resolve, reject) => {
120
+ const timeout = setTimeout(() => {
121
+ pending.delete(id);
122
+ abandoned.add(id);
123
+ if (abandoned.size > 256) abandoned.delete(abandoned.values().next().value);
124
+ reject(new Error(`${TIMEOUT_PREFIX}: ${capability}.${method}`));
125
+ }, timeoutMs);
126
+ pending.set(id, { resolve, reject, timeout });
127
+ if (!bridge.post(request)) {
128
+ clearTimeout(timeout);
129
+ pending.delete(id);
130
+ reject(new Error("@himalaya/webview-page: the native page-to-worker bridge refused the request."));
131
+ }
113
132
  });
114
- });
133
+ }
134
+ function on2(namespace2, event, handler) {
135
+ workerBridge();
136
+ if (typeof handler !== "function") throw new Error("@himalaya/webview-page: on() needs a handler function");
137
+ let byEvent = listeners.get(namespace2);
138
+ if (!byEvent) listeners.set(namespace2, byEvent = /* @__PURE__ */ new Map());
139
+ let handlers = byEvent.get(event);
140
+ if (!handlers) byEvent.set(event, handlers = /* @__PURE__ */ new Set());
141
+ const entry = (data) => handler(data);
142
+ handlers.add(entry);
143
+ return () => {
144
+ handlers.delete(entry);
145
+ };
146
+ }
147
+ let manifest;
148
+ function currentBridge() {
149
+ try {
150
+ return workerBridge();
151
+ } catch {
152
+ return void 0;
153
+ }
154
+ }
155
+ function timedOut(error) {
156
+ return error instanceof Error && error.message.startsWith(TIMEOUT_PREFIX);
157
+ }
158
+ let asking;
159
+ function askShared(target, budget) {
160
+ const until = Date.now() + budget;
161
+ if (asking?.on === target) {
162
+ asking.until = Math.max(asking.until, until);
163
+ return asking.answer;
164
+ }
165
+ const state = { on: target, until, answer: Promise.resolve(null) };
166
+ asking = state;
167
+ state.answer = new Promise((resolve) => {
168
+ let done = false;
169
+ const finish = (list) => {
170
+ if (done) return;
171
+ done = true;
172
+ clearInterval(again);
173
+ if (asking === state) asking = void 0;
174
+ if (list) manifest = { on: target, list };
175
+ resolve(list);
176
+ };
177
+ const ask = () => {
178
+ if (done) return;
179
+ const left = state.until - Date.now();
180
+ if (left <= 0 || currentBridge() !== target) return finish(null);
181
+ call2("himalaya", "capabilities", [], Math.max(1, Math.min(2e3, left))).then(
182
+ (reply) => finish(reply?.capabilities ?? null),
183
+ // A timed-out question is not an answer; the deadline decides. Anything else is final.
184
+ (error) => {
185
+ if (!timedOut(error)) finish(null);
186
+ }
187
+ );
188
+ };
189
+ const again = setInterval(ask, 500);
190
+ ask();
191
+ });
192
+ return state.answer;
193
+ }
194
+ async function enabledCapabilities2(timeoutMs = 3e3) {
195
+ const bridge = currentBridge();
196
+ if (!bridge) return null;
197
+ if (manifest?.on === bridge) return manifest.list;
198
+ if (!(timeoutMs > 0)) return null;
199
+ const budget = Math.min(timeoutMs, 2147483647);
200
+ const answer = askShared(bridge, budget);
201
+ return new Promise((resolve) => {
202
+ const stop = setTimeout(() => resolve(manifest?.on === bridge ? manifest.list : null), budget);
203
+ void answer.then((list) => {
204
+ clearTimeout(stop);
205
+ resolve(list);
206
+ });
207
+ });
208
+ }
209
+ async function isEnabled2(capability, method, timeoutMs = 3e3) {
210
+ const enabled = await enabledCapabilities2(timeoutMs);
211
+ return enabled?.[capability]?.includes(method) ?? false;
212
+ }
213
+ async function probe2(capability, method, args = [], timeoutMs = 3e3) {
214
+ if (!currentBridge()) return false;
215
+ try {
216
+ const result = await call2(capability, method, args, timeoutMs);
217
+ const iterate = result?.[Symbol.asyncIterator];
218
+ if (typeof iterate === "function") void iterate.call(result).return?.();
219
+ return true;
220
+ } catch (error) {
221
+ if (error.code === "unknown_method") return false;
222
+ return !(timedOut(error) || /refused the request/.test(error.message));
223
+ }
224
+ }
225
+ const members = /* @__PURE__ */ new Map();
226
+ function pageMember(capability, path) {
227
+ const key = `${capability}:${path.join(".")}`;
228
+ let member = members.get(key);
229
+ if (member) return member;
230
+ const label = `[himalaya.${[capability, ...path].join(".")}]`;
231
+ member = new Proxy((() => {
232
+ }), {
233
+ get(_target, property) {
234
+ if (typeof property !== "string" || property === "then") return void 0;
235
+ if (property === "toString" || property === "valueOf") return () => label;
236
+ if (path.length === 0 && property === "on") {
237
+ return (event, handler) => on2(capability, event, handler);
238
+ }
239
+ return pageMember(capability, [...path, property]);
240
+ },
241
+ apply(_target, _thisArg, args) {
242
+ if (path.length === 0) throw new Error(`Himalaya capability namespace is not callable: ${capability}`);
243
+ return call2(capability, path.join("."), args);
244
+ }
245
+ });
246
+ members.set(key, member);
247
+ return member;
248
+ }
249
+ const namespace = (capability) => pageMember(capability, []);
250
+ function merge(target) {
251
+ const own = { call: call2, on: on2, enabledCapabilities: enabledCapabilities2, isEnabled: isEnabled2, probe: probe2, version: 1 };
252
+ for (const name of Object.keys(own)) {
253
+ if (!Object.prototype.hasOwnProperty.call(target, name)) {
254
+ Object.defineProperty(target, name, { value: own[name], enumerable: true, writable: false, configurable: false });
255
+ }
256
+ }
257
+ Object.freeze(target);
258
+ return new Proxy(target, {
259
+ get(t, property, receiver) {
260
+ if (typeof property !== "string" || property in t) return Reflect.get(t, property, receiver);
261
+ if (property === "then") return void 0;
262
+ return namespace(property);
263
+ }
264
+ });
265
+ }
266
+ return { call: call2, on: on2, enabledCapabilities: enabledCapabilities2, isEnabled: isEnabled2, probe: probe2, namespace, merge };
267
+ }
268
+
269
+ // ../../core/sdk/webview-page/src/index.ts
270
+ var client = createPageClient(() => globalThis.HimalayaWorker);
271
+ function call(capability, method, args = [], timeoutMs = 3e4) {
272
+ return client.call(capability, method, args, timeoutMs);
115
273
  }
116
- async function isEnabled(capability, method, timeoutMs = 3e3) {
117
- const enabled = await enabledCapabilities(timeoutMs);
118
- return enabled?.[capability]?.includes(method) ?? false;
274
+ function on(namespace, event, handler) {
275
+ return client.on(namespace, event, handler);
119
276
  }
120
- async function probe(capability, method, args = [], timeoutMs = 3e3) {
121
- if (!currentBridge()) return false;
122
- try {
123
- await call(capability, method, args, timeoutMs);
124
- return true;
125
- } catch (error) {
126
- return !(timedOut(error) || /refused the request/.test(error.message));
127
- }
277
+ function enabledCapabilities(timeoutMs = 3e3) {
278
+ return client.enabledCapabilities(timeoutMs);
128
279
  }
129
- var members = /* @__PURE__ */ new Map();
130
- function pageMember(capability, path) {
131
- const key = `${capability}:${path.join(".")}`;
132
- let member = members.get(key);
133
- if (member) return member;
134
- member = new Proxy(function() {
135
- }, {
136
- get(_target, property) {
137
- if (typeof property !== "string" || property === "then") return void 0;
138
- return pageMember(capability, [...path, property]);
139
- },
140
- apply(_target, _thisArg, args) {
141
- if (path.length === 0) throw new Error(`Himalaya capability namespace is not callable: ${capability}`);
142
- return call(capability, path.join("."), args);
143
- }
144
- });
145
- members.set(key, member);
146
- return member;
280
+ function isEnabled(capability, method, timeoutMs = 3e3) {
281
+ return client.isEnabled(capability, method, timeoutMs);
147
282
  }
148
- var himalaya = new Proxy({ version: 1 }, {
149
- get(target, property) {
150
- if (property === "version") return target.version;
151
- if (typeof property !== "string" || property === "then") return void 0;
152
- return pageMember(property, []);
153
- }
154
- });
283
+ function probe(capability, method, args = [], timeoutMs = 3e3) {
284
+ return client.probe(capability, method, args, timeoutMs);
285
+ }
286
+ var himalaya = client.merge({});
155
287
  var health = himalaya.health;
156
288
  var version = 1;
157
289
  export {
@@ -160,6 +292,7 @@ export {
160
292
  health,
161
293
  himalaya,
162
294
  isEnabled,
295
+ on,
163
296
  probe,
164
297
  version
165
298
  };