@wix/himalaya-cli 0.1451.0 → 0.1453.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview/src/dispatcher.d.ts +79 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview/src/index.d.ts +41 -30
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview-page/src/capabilities.generated.d.ts +47 -41
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview-page/src/client.d.ts +68 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview-page/src/index.d.ts +13 -21
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/webview-page.mjs +277 -144
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/webview.mjs +505 -49
- package/guides/designing-himi-screens.md +34 -1
- package/guides/index.json +1 -0
- package/guides/sdk-reference.json +45 -45
- package/guides/web-page-native-sdk.md +4 -3
- package/guides/webview-page-sdk.md +102 -3
- package/package.json +2 -2
|
@@ -1,157 +1,289 @@
|
|
|
1
|
-
// ../../core/sdk/webview-page/src/
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
return enabled?.[capability]?.includes(method) ?? false;
|
|
274
|
+
function on(namespace, event, handler) {
|
|
275
|
+
return client.on(namespace, event, handler);
|
|
119
276
|
}
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
130
|
-
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
};
|