@egen-civitas/esm-platform 0.0.0-stage → 1.2.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/CHANGELOG.md +29 -0
- package/README.md +117 -2
- package/dist/adapters/web/camera.d.ts +10 -0
- package/dist/adapters/web/camera.js +31 -0
- package/dist/adapters/web/file-registry.d.ts +7 -0
- package/dist/adapters/web/file-registry.js +26 -0
- package/dist/adapters/web/files.d.ts +7 -0
- package/dist/adapters/web/files.js +22 -0
- package/dist/adapters/web/index.d.ts +9 -0
- package/dist/adapters/web/index.js +9 -0
- package/dist/adapters/web/lifecycle.d.ts +3 -0
- package/dist/adapters/web/lifecycle.js +20 -0
- package/dist/adapters/web/open-external.d.ts +8 -0
- package/dist/adapters/web/open-external.js +32 -0
- package/dist/adapters/web/permissions.d.ts +12 -0
- package/dist/adapters/web/permissions.js +48 -0
- package/dist/adapters/web/pick-files.d.ts +17 -0
- package/dist/adapters/web/pick-files.js +49 -0
- package/dist/adapters/web/session.d.ts +12 -0
- package/dist/adapters/web/session.js +19 -0
- package/dist/adapters/web/web-adapter.test.js +1233 -0
- package/dist/bridge/client.d.ts +48 -0
- package/dist/bridge/client.js +212 -0
- package/dist/bridge/client.test.js +1264 -0
- package/dist/bridge/index.d.ts +4 -0
- package/dist/bridge/index.js +2 -0
- package/dist/bridge/protocol.d.ts +72 -0
- package/dist/bridge/protocol.js +66 -0
- package/dist/bridge/protocol.test.js +215 -0
- package/dist/capabilities.d.ts +34 -0
- package/dist/capabilities.js +48 -0
- package/dist/detect.d.ts +25 -0
- package/dist/detect.js +38 -0
- package/dist/detect.test.js +23 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.js +27 -0
- package/dist/errors.test.js +31 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +14 -0
- package/dist/native-platform.test.js +329 -0
- package/dist/native.d.ts +24 -0
- package/dist/native.js +46 -0
- package/dist/platform.d.ts +24 -0
- package/dist/platform.js +56 -0
- package/dist/platform.test.js +696 -0
- package/dist/register-capabilities.test.js +188 -0
- package/dist/registry.d.ts +52 -0
- package/dist/registry.js +101 -0
- package/dist/registry.test.js +681 -0
- package/dist/testing/index.d.ts +23 -0
- package/dist/testing/index.js +14 -0
- package/dist/testing/mock-host.d.ts +49 -0
- package/dist/testing/mock-host.js +86 -0
- package/dist/types.d.ts +108 -0
- package/dist/types.js +1 -0
- package/package.json +57 -3
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
2
|
+
try {
|
|
3
|
+
var info = gen[key](arg);
|
|
4
|
+
var value = info.value;
|
|
5
|
+
} catch (error) {
|
|
6
|
+
reject(error);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (info.done) {
|
|
10
|
+
resolve(value);
|
|
11
|
+
} else {
|
|
12
|
+
Promise.resolve(value).then(_next, _throw);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function _async_to_generator(fn) {
|
|
16
|
+
return function() {
|
|
17
|
+
var self = this, args = arguments;
|
|
18
|
+
return new Promise(function(resolve, reject) {
|
|
19
|
+
var gen = fn.apply(self, args);
|
|
20
|
+
function _next(value) {
|
|
21
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
22
|
+
}
|
|
23
|
+
function _throw(err) {
|
|
24
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
25
|
+
}
|
|
26
|
+
_next(undefined);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function _ts_generator(thisArg, body) {
|
|
31
|
+
var f, y, t, _ = {
|
|
32
|
+
label: 0,
|
|
33
|
+
sent: function() {
|
|
34
|
+
if (t[0] & 1) throw t[1];
|
|
35
|
+
return t[1];
|
|
36
|
+
},
|
|
37
|
+
trys: [],
|
|
38
|
+
ops: []
|
|
39
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
40
|
+
return d(g, "next", {
|
|
41
|
+
value: verb(0)
|
|
42
|
+
}), d(g, "throw", {
|
|
43
|
+
value: verb(1)
|
|
44
|
+
}), d(g, "return", {
|
|
45
|
+
value: verb(2)
|
|
46
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
47
|
+
value: function() {
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
}), g;
|
|
51
|
+
function verb(n) {
|
|
52
|
+
return function(v) {
|
|
53
|
+
return step([
|
|
54
|
+
n,
|
|
55
|
+
v
|
|
56
|
+
]);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function step(op) {
|
|
60
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
61
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
62
|
+
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;
|
|
63
|
+
if (y = 0, t) op = [
|
|
64
|
+
op[0] & 2,
|
|
65
|
+
t.value
|
|
66
|
+
];
|
|
67
|
+
switch(op[0]){
|
|
68
|
+
case 0:
|
|
69
|
+
case 1:
|
|
70
|
+
t = op;
|
|
71
|
+
break;
|
|
72
|
+
case 4:
|
|
73
|
+
_.label++;
|
|
74
|
+
return {
|
|
75
|
+
value: op[1],
|
|
76
|
+
done: false
|
|
77
|
+
};
|
|
78
|
+
case 5:
|
|
79
|
+
_.label++;
|
|
80
|
+
y = op[1];
|
|
81
|
+
op = [
|
|
82
|
+
0
|
|
83
|
+
];
|
|
84
|
+
continue;
|
|
85
|
+
case 7:
|
|
86
|
+
op = _.ops.pop();
|
|
87
|
+
_.trys.pop();
|
|
88
|
+
continue;
|
|
89
|
+
default:
|
|
90
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
91
|
+
_ = 0;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
95
|
+
_.label = op[1];
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
99
|
+
_.label = t[1];
|
|
100
|
+
t = op;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
if (t && _.label < t[2]) {
|
|
104
|
+
_.label = t[2];
|
|
105
|
+
_.ops.push(op);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
if (t[2]) _.ops.pop();
|
|
109
|
+
_.trys.pop();
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
op = body.call(thisArg, _);
|
|
113
|
+
} catch (e) {
|
|
114
|
+
op = [
|
|
115
|
+
6,
|
|
116
|
+
e
|
|
117
|
+
];
|
|
118
|
+
y = 0;
|
|
119
|
+
} finally{
|
|
120
|
+
f = t = 0;
|
|
121
|
+
}
|
|
122
|
+
if (op[0] & 5) throw op[1];
|
|
123
|
+
return {
|
|
124
|
+
value: op[0] ? op[1] : void 0,
|
|
125
|
+
done: true
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
130
|
+
import { getHostInfo, getPlatform, registerPlatformCapabilities } from './index';
|
|
131
|
+
import { createMockHost } from './testing';
|
|
132
|
+
afterEach(function() {
|
|
133
|
+
var w = window;
|
|
134
|
+
delete w.egenTarget;
|
|
135
|
+
delete w.egenHostBridge;
|
|
136
|
+
});
|
|
137
|
+
describe('getPlatform() natif — handshake avec le Host', function() {
|
|
138
|
+
it('ready attend le handshake ; getHostInfo() expose ce que le Host a annoncé', function() {
|
|
139
|
+
return _async_to_generator(function() {
|
|
140
|
+
var host;
|
|
141
|
+
return _ts_generator(this, function(_state) {
|
|
142
|
+
switch(_state.label){
|
|
143
|
+
case 0:
|
|
144
|
+
window.egenTarget = 'android';
|
|
145
|
+
host = createMockHost({
|
|
146
|
+
host: '4.2.0',
|
|
147
|
+
capabilities: {
|
|
148
|
+
secureStorage: {
|
|
149
|
+
v: 1
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
host.install();
|
|
154
|
+
expect(getHostInfo()).toBeNull(); // pas encore de handshake
|
|
155
|
+
return [
|
|
156
|
+
4,
|
|
157
|
+
getPlatform().ready
|
|
158
|
+
];
|
|
159
|
+
case 1:
|
|
160
|
+
_state.sent();
|
|
161
|
+
expect(getHostInfo()).toEqual({
|
|
162
|
+
protocol: 1,
|
|
163
|
+
host: '4.2.0',
|
|
164
|
+
platform: 'android',
|
|
165
|
+
capabilities: {
|
|
166
|
+
secureStorage: {
|
|
167
|
+
v: 1
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
return [
|
|
172
|
+
2
|
|
173
|
+
];
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
})();
|
|
177
|
+
});
|
|
178
|
+
it('plusieurs getPlatform() partagent UN SEUL handshake et UN SEUL abonnement', function() {
|
|
179
|
+
return _async_to_generator(function() {
|
|
180
|
+
var host;
|
|
181
|
+
return _ts_generator(this, function(_state) {
|
|
182
|
+
switch(_state.label){
|
|
183
|
+
case 0:
|
|
184
|
+
window.egenTarget = 'android';
|
|
185
|
+
host = createMockHost();
|
|
186
|
+
host.install();
|
|
187
|
+
return [
|
|
188
|
+
4,
|
|
189
|
+
Promise.all([
|
|
190
|
+
getPlatform().ready,
|
|
191
|
+
getPlatform().ready,
|
|
192
|
+
getPlatform().ready
|
|
193
|
+
])
|
|
194
|
+
];
|
|
195
|
+
case 1:
|
|
196
|
+
_state.sent();
|
|
197
|
+
return [
|
|
198
|
+
4,
|
|
199
|
+
getPlatform().ready
|
|
200
|
+
];
|
|
201
|
+
case 2:
|
|
202
|
+
_state.sent();
|
|
203
|
+
expect(host.sent.filter(function(r) {
|
|
204
|
+
return r.m === 'hello';
|
|
205
|
+
})).toHaveLength(1);
|
|
206
|
+
expect(host.subscribeCount).toBe(1);
|
|
207
|
+
return [
|
|
208
|
+
2
|
|
209
|
+
];
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
})();
|
|
213
|
+
});
|
|
214
|
+
it('Host de version de protocole incompatible ⇒ ready rejette INCOMPATIBLE', function() {
|
|
215
|
+
return _async_to_generator(function() {
|
|
216
|
+
return _ts_generator(this, function(_state) {
|
|
217
|
+
switch(_state.label){
|
|
218
|
+
case 0:
|
|
219
|
+
window.egenTarget = 'ios';
|
|
220
|
+
createMockHost({
|
|
221
|
+
platform: 'ios',
|
|
222
|
+
protocol: 2
|
|
223
|
+
}).install();
|
|
224
|
+
return [
|
|
225
|
+
4,
|
|
226
|
+
expect(getPlatform().ready).rejects.toMatchObject({
|
|
227
|
+
code: 'INCOMPATIBLE'
|
|
228
|
+
})
|
|
229
|
+
];
|
|
230
|
+
case 1:
|
|
231
|
+
_state.sent();
|
|
232
|
+
expect(getHostInfo()).toBeNull();
|
|
233
|
+
return [
|
|
234
|
+
2
|
|
235
|
+
];
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
})();
|
|
239
|
+
});
|
|
240
|
+
it('Host qui annonce une autre plateforme que la cible du build ⇒ INCOMPATIBLE', function() {
|
|
241
|
+
return _async_to_generator(function() {
|
|
242
|
+
return _ts_generator(this, function(_state) {
|
|
243
|
+
switch(_state.label){
|
|
244
|
+
case 0:
|
|
245
|
+
window.egenTarget = 'ios';
|
|
246
|
+
createMockHost({
|
|
247
|
+
platform: 'android'
|
|
248
|
+
}).install();
|
|
249
|
+
return [
|
|
250
|
+
4,
|
|
251
|
+
expect(getPlatform().ready).rejects.toMatchObject({
|
|
252
|
+
code: 'INCOMPATIBLE'
|
|
253
|
+
})
|
|
254
|
+
];
|
|
255
|
+
case 1:
|
|
256
|
+
_state.sent();
|
|
257
|
+
return [
|
|
258
|
+
2
|
|
259
|
+
];
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
})();
|
|
263
|
+
});
|
|
264
|
+
it("tant que les adaptateurs natifs (C7) n'existent pas, aucune capacité n'est disponible — même annoncée par le Host", function() {
|
|
265
|
+
return _async_to_generator(function() {
|
|
266
|
+
var platform;
|
|
267
|
+
return _ts_generator(this, function(_state) {
|
|
268
|
+
switch(_state.label){
|
|
269
|
+
case 0:
|
|
270
|
+
window.egenTarget = 'android';
|
|
271
|
+
createMockHost({
|
|
272
|
+
capabilities: {
|
|
273
|
+
secureStorage: {
|
|
274
|
+
v: 1
|
|
275
|
+
},
|
|
276
|
+
session: {
|
|
277
|
+
v: 1
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}).install();
|
|
281
|
+
platform = getPlatform();
|
|
282
|
+
return [
|
|
283
|
+
4,
|
|
284
|
+
platform.ready
|
|
285
|
+
];
|
|
286
|
+
case 1:
|
|
287
|
+
_state.sent();
|
|
288
|
+
expect(platform.has('secureStorage')).toBe(false);
|
|
289
|
+
return [
|
|
290
|
+
4,
|
|
291
|
+
expect(platform.secureStorage.get('k')).rejects.toMatchObject({
|
|
292
|
+
code: 'UNAVAILABLE'
|
|
293
|
+
})
|
|
294
|
+
];
|
|
295
|
+
case 2:
|
|
296
|
+
_state.sent();
|
|
297
|
+
return [
|
|
298
|
+
2
|
|
299
|
+
];
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
})();
|
|
303
|
+
});
|
|
304
|
+
it('registerPlatformCapabilities() attend le handshake natif', function() {
|
|
305
|
+
return _async_to_generator(function() {
|
|
306
|
+
var host;
|
|
307
|
+
return _ts_generator(this, function(_state) {
|
|
308
|
+
switch(_state.label){
|
|
309
|
+
case 0:
|
|
310
|
+
window.egenTarget = 'android';
|
|
311
|
+
host = createMockHost();
|
|
312
|
+
host.install();
|
|
313
|
+
return [
|
|
314
|
+
4,
|
|
315
|
+
expect(registerPlatformCapabilities()).resolves.toBeUndefined()
|
|
316
|
+
];
|
|
317
|
+
case 1:
|
|
318
|
+
_state.sent();
|
|
319
|
+
expect(host.sent.some(function(r) {
|
|
320
|
+
return r.m === 'hello';
|
|
321
|
+
})).toBe(true);
|
|
322
|
+
return [
|
|
323
|
+
2
|
|
324
|
+
];
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
})();
|
|
328
|
+
});
|
|
329
|
+
});
|
package/dist/native.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type BridgeClient, type HostInfo } from './bridge/client.js';
|
|
2
|
+
import type { HostBridge } from './bridge/protocol.js';
|
|
3
|
+
import type { CapabilityOverrides } from './capabilities.js';
|
|
4
|
+
import type { PlatformEnvironment } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Client du pont donné. `getPlatform()` est appelé plusieurs fois (démarrage, apps) : sans ce partage, chaque appel
|
|
7
|
+
* referait un `subscribe` et un handshake. Un seul client par pont ⇒ un seul handshake (`hello()` est mémorisé : une
|
|
8
|
+
* incompatibilité reste rejetée, un échec passager comme un timeout peut être rejoué).
|
|
9
|
+
*/
|
|
10
|
+
export declare function getNativeClient(bridge: HostBridge, environment: PlatformEnvironment): BridgeClient;
|
|
11
|
+
/**
|
|
12
|
+
* Capacités natives implémentées par le framework, branchées sur le client de pont : celles dont l'entrée du registre
|
|
13
|
+
* (`registry.ts`) déclare un adaptateur `native`. AUCUNE tant que les adaptateurs natifs (tâche C7) ne sont pas écrits :
|
|
14
|
+
* `has()` reste faux partout, même si le Host annonce la capacité — on ne promet jamais ce que le framework ne sait
|
|
15
|
+
* pas encore appeler.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createNativeCapabilities(client: BridgeClient): CapabilityOverrides;
|
|
18
|
+
/**
|
|
19
|
+
* Ce que le Host a annoncé au handshake (version de protocole, version du Host, capacités), ou `null` si le
|
|
20
|
+
* handshake n'a pas (encore) réussi. Utile au diagnostic et à la validation de compatibilité.
|
|
21
|
+
*
|
|
22
|
+
* @category Platform
|
|
23
|
+
*/
|
|
24
|
+
export declare function getHostInfo(): HostInfo | null;
|
package/dist/native.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createBridgeClient } from './bridge/client.js';
|
|
2
|
+
import { getHostBridge } from './detect.js';
|
|
3
|
+
import { createNativeCapabilitiesFromRegistry } from './registry.js';
|
|
4
|
+
/** Un client de pont par pont : ses abonnements et son handshake sont partagés par tous les `getPlatform()` de la page. */
|
|
5
|
+
const clients = new WeakMap();
|
|
6
|
+
function frameworkVersion() {
|
|
7
|
+
try {
|
|
8
|
+
// Remplacé à la compilation par le DefinePlugin du shell ; absent (ReferenceError) hors bundle.
|
|
9
|
+
return process.env.FRAMEWORK_VERSION || undefined;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Client du pont donné. `getPlatform()` est appelé plusieurs fois (démarrage, apps) : sans ce partage, chaque appel
|
|
17
|
+
* referait un `subscribe` et un handshake. Un seul client par pont ⇒ un seul handshake (`hello()` est mémorisé : une
|
|
18
|
+
* incompatibilité reste rejetée, un échec passager comme un timeout peut être rejoué).
|
|
19
|
+
*/
|
|
20
|
+
export function getNativeClient(bridge, environment) {
|
|
21
|
+
let client = clients.get(bridge);
|
|
22
|
+
if (!client) {
|
|
23
|
+
client = createBridgeClient({ bridge, environment, framework: frameworkVersion() });
|
|
24
|
+
clients.set(bridge, client);
|
|
25
|
+
}
|
|
26
|
+
return client;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Capacités natives implémentées par le framework, branchées sur le client de pont : celles dont l'entrée du registre
|
|
30
|
+
* (`registry.ts`) déclare un adaptateur `native`. AUCUNE tant que les adaptateurs natifs (tâche C7) ne sont pas écrits :
|
|
31
|
+
* `has()` reste faux partout, même si le Host annonce la capacité — on ne promet jamais ce que le framework ne sait
|
|
32
|
+
* pas encore appeler.
|
|
33
|
+
*/
|
|
34
|
+
export function createNativeCapabilities(client) {
|
|
35
|
+
return createNativeCapabilitiesFromRegistry(client);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Ce que le Host a annoncé au handshake (version de protocole, version du Host, capacités), ou `null` si le
|
|
39
|
+
* handshake n'a pas (encore) réussi. Utile au diagnostic et à la validation de compatibilité.
|
|
40
|
+
*
|
|
41
|
+
* @category Platform
|
|
42
|
+
*/
|
|
43
|
+
export function getHostInfo() {
|
|
44
|
+
const bridge = getHostBridge();
|
|
45
|
+
return bridge ? (clients.get(bridge)?.hostInfo ?? null) : null;
|
|
46
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Platform } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Point d'accès unique des apps aux capacités de plateforme.
|
|
4
|
+
*
|
|
5
|
+
* La cible est fixée au build (`window.egenTarget`).
|
|
6
|
+
* - Web : capacités du navigateur (adaptateur C4), rien à attendre.
|
|
7
|
+
* - Natif : le Host DOIT avoir injecté `window.egenHostBridge` avant tout script de la page, sinon `ready` rejette
|
|
8
|
+
* `INCOMPATIBLE` (« Host manquant »). `ready` est le handshake de protocole (version, plateforme, capacités). Une
|
|
9
|
+
* capacité n'est disponible que si le Host l'annonce ET que le framework sait l'appeler : tant que les adaptateurs
|
|
10
|
+
* natifs (C7) ne sont pas écrits, `has()` est faux partout et chaque méthode rejette `UNAVAILABLE`.
|
|
11
|
+
*
|
|
12
|
+
* @category Platform
|
|
13
|
+
*/
|
|
14
|
+
export declare function getPlatform(): Platform;
|
|
15
|
+
/**
|
|
16
|
+
* Rend les capacités de la plateforme consultables par le reste du framework (filtrage `requiredCapabilities`
|
|
17
|
+
* des apps, F2) et retourne `platform.ready`.
|
|
18
|
+
*
|
|
19
|
+
* À appeler UNE fois au démarrage, AVANT l'enregistrement des apps. Le résolveur est posé immédiatement : si `ready`
|
|
20
|
+
* rejette (natif sans Host), `has()` reste faux partout — aucune capacité n'est jamais supposée.
|
|
21
|
+
*
|
|
22
|
+
* @category Platform
|
|
23
|
+
*/
|
|
24
|
+
export declare function registerPlatformCapabilities(platform?: Platform): Promise<void>;
|
package/dist/platform.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { setCapabilityResolver } from '@egen-civitas/esm-globals';
|
|
2
|
+
import { assemblePlatform } from './capabilities.js';
|
|
3
|
+
import { getHostBridge, getPlatformEnvironment } from './detect.js';
|
|
4
|
+
import { PlatformError } from './errors.js';
|
|
5
|
+
import { createNativeCapabilities, getNativeClient } from './native.js';
|
|
6
|
+
import { createWebCapabilities, isHostVersionSufficient } from './registry.js';
|
|
7
|
+
function hostMissing(environment) {
|
|
8
|
+
return new PlatformError('INCOMPATIBLE', `Host manquant : la cible "${environment}" exige que l'application hôte injecte window.egenHostBridge avant le chargement de la page.`);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Point d'accès unique des apps aux capacités de plateforme.
|
|
12
|
+
*
|
|
13
|
+
* La cible est fixée au build (`window.egenTarget`).
|
|
14
|
+
* - Web : capacités du navigateur (adaptateur C4), rien à attendre.
|
|
15
|
+
* - Natif : le Host DOIT avoir injecté `window.egenHostBridge` avant tout script de la page, sinon `ready` rejette
|
|
16
|
+
* `INCOMPATIBLE` (« Host manquant »). `ready` est le handshake de protocole (version, plateforme, capacités). Une
|
|
17
|
+
* capacité n'est disponible que si le Host l'annonce ET que le framework sait l'appeler : tant que les adaptateurs
|
|
18
|
+
* natifs (C7) ne sont pas écrits, `has()` est faux partout et chaque méthode rejette `UNAVAILABLE`.
|
|
19
|
+
*
|
|
20
|
+
* @category Platform
|
|
21
|
+
*/
|
|
22
|
+
export function getPlatform() {
|
|
23
|
+
const environment = getPlatformEnvironment();
|
|
24
|
+
if (environment === 'web') {
|
|
25
|
+
return assemblePlatform({
|
|
26
|
+
environment,
|
|
27
|
+
capabilities: createWebCapabilities(),
|
|
28
|
+
ready: () => Promise.resolve(),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const bridge = getHostBridge();
|
|
32
|
+
if (!bridge) {
|
|
33
|
+
return assemblePlatform({ environment, ready: () => Promise.reject(hostMissing(environment)) });
|
|
34
|
+
}
|
|
35
|
+
const client = getNativeClient(bridge, environment);
|
|
36
|
+
return assemblePlatform({
|
|
37
|
+
environment,
|
|
38
|
+
capabilities: createNativeCapabilities(client),
|
|
39
|
+
ready: () => client.hello().then(() => undefined),
|
|
40
|
+
// Annoncée par le Host ET dans une version suffisante pour l'adaptateur de ce framework (registre).
|
|
41
|
+
available: (capability) => isHostVersionSufficient(capability, client.hostInfo?.capabilities[capability]?.v),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Rend les capacités de la plateforme consultables par le reste du framework (filtrage `requiredCapabilities`
|
|
46
|
+
* des apps, F2) et retourne `platform.ready`.
|
|
47
|
+
*
|
|
48
|
+
* À appeler UNE fois au démarrage, AVANT l'enregistrement des apps. Le résolveur est posé immédiatement : si `ready`
|
|
49
|
+
* rejette (natif sans Host), `has()` reste faux partout — aucune capacité n'est jamais supposée.
|
|
50
|
+
*
|
|
51
|
+
* @category Platform
|
|
52
|
+
*/
|
|
53
|
+
export function registerPlatformCapabilities(platform = getPlatform()) {
|
|
54
|
+
setCapabilityResolver((capability) => platform.has(capability));
|
|
55
|
+
return platform.ready;
|
|
56
|
+
}
|