@omriashke/dynamico-core 0.1.0 → 0.1.1
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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +4 -1
- package/dist/loader.js.map +1 -1
- package/dist/propsSchema.d.ts.map +1 -1
- package/dist/propsSchema.js +3 -0
- package/dist/propsSchema.js.map +1 -1
- package/dist/react/createRuntime.d.ts +23 -1
- package/dist/react/createRuntime.d.ts.map +1 -1
- package/dist/react/createRuntime.js +29 -11
- package/dist/react/createRuntime.js.map +1 -1
- package/dist/registry.d.ts +6 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +8 -0
- package/dist/registry.js.map +1 -1
- package/dist/sources/remote.d.ts +12 -0
- package/dist/sources/remote.d.ts.map +1 -1
- package/dist/sources/remote.js +34 -2
- package/dist/sources/remote.js.map +1 -1
- package/dist/types.d.ts +16 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +1 -0
- package/src/loader.ts +4 -1
- package/src/propsSchema.ts +2 -0
- package/src/react/createRuntime.tsx +59 -14
- package/src/registry.ts +9 -0
- package/src/sources/remote.ts +52 -2
- package/src/types.ts +23 -2
package/dist/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export { Registry } from "./registry.js";
|
|
|
3
3
|
export { loadModule } from "./loader.js";
|
|
4
4
|
export { createRemoteSource, type RemoteSourceOptions } from "./sources/remote.js";
|
|
5
5
|
export { validateProps, type PropsValidationResult } from "./propsSchema.js";
|
|
6
|
-
export { createRuntime, type RuntimeAPI, type DynamicoProviderProps, type DynamicComponentProps, } from "./react/createRuntime.js";
|
|
6
|
+
export { createRuntime, type RuntimeAPI, type CreateRuntimeOptions, type DynamicoProviderProps, type DynamicComponentProps, } from "./react/createRuntime.js";
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,MAAM,EACN,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,OAAO,GACR,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EACL,aAAa,EACb,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,MAAM,EACN,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,OAAO,GACR,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EACL,aAAa,EACb,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAA4B,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,aAAa,EAA8B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EACL,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAA4B,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,aAAa,EAA8B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EACL,aAAa,GAKd,MAAM,0BAA0B,CAAC"}
|
package/dist/loader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,EACZ,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,GAC9C,OAAO,
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,EACZ,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,GAC9C,OAAO,CAuBT"}
|
package/dist/loader.js
CHANGED
|
@@ -17,7 +17,10 @@ export function loadModule(code, scope, requireRelative) {
|
|
|
17
17
|
if (name.startsWith("./") || name.startsWith("../") || name.startsWith("/")) {
|
|
18
18
|
return requireRelative(name);
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
// Use `in` (triggers Proxy `has` traps) so that hosts can supply scope
|
|
21
|
+
// via a Proxy and resolve module bindings lazily. Falls back to
|
|
22
|
+
// `hasOwnProperty` semantics for plain object scopes.
|
|
23
|
+
if (name in scope) {
|
|
21
24
|
return scope[name];
|
|
22
25
|
}
|
|
23
26
|
throw new Error(`dynamico: '${name}' is not in host scope. Add it via <DynamicoProvider scope={{...}}>.`);
|
package/dist/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,KAAY,EACZ,eAA+C;IAE/C,MAAM,SAAS,GAAG,EAAE,OAAO,EAAE,EAA6B,EAAE,CAAC;IAC7D,MAAM,SAAS,GAAG,CAAC,IAAY,EAAW,EAAE;QAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5E,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,KAAY,EACZ,eAA+C;IAE/C,MAAM,SAAS,GAAG,EAAE,OAAO,EAAE,EAA6B,EAAE,CAAC;IAC7D,MAAM,SAAS,GAAG,CAAC,IAAY,EAAW,EAAE;QAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5E,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,uEAAuE;QACvE,gEAAgE;QAChE,sDAAsD;QACtD,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;YAClB,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QACD,MAAM,IAAI,KAAK,CACb,cAAc,IAAI,sEAAsE,CACzF,CAAC;IACJ,CAAC,CAAC;IAEF,yEAAyE;IACzE,uCAAuC;IACvC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9D,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAE5C,OAAO,SAAS,CAAC,OAAO,CAAC;AAC3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"propsSchema.d.ts","sourceRoot":"","sources":["../src/propsSchema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"propsSchema.d.ts","sourceRoot":"","sources":["../src/propsSchema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAYD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,qBAAqB,CAiBvB"}
|
package/dist/propsSchema.js
CHANGED
|
@@ -4,6 +4,7 @@ const TYPE_CHECKS = {
|
|
|
4
4
|
boolean: (v) => typeof v === "boolean",
|
|
5
5
|
object: (v) => typeof v === "object" && v !== null && !Array.isArray(v),
|
|
6
6
|
array: (v) => Array.isArray(v),
|
|
7
|
+
function: (v) => typeof v === "function",
|
|
7
8
|
any: () => true,
|
|
8
9
|
};
|
|
9
10
|
export function validateProps(schema, props) {
|
|
@@ -29,6 +30,8 @@ function describe(v) {
|
|
|
29
30
|
return "null";
|
|
30
31
|
if (Array.isArray(v))
|
|
31
32
|
return "array";
|
|
33
|
+
if (typeof v === "function")
|
|
34
|
+
return "function";
|
|
32
35
|
return typeof v;
|
|
33
36
|
}
|
|
34
37
|
//# sourceMappingURL=propsSchema.js.map
|
package/dist/propsSchema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"propsSchema.js","sourceRoot":"","sources":["../src/propsSchema.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,GAA4C;IAC3D,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ;IACpC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxD,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS;IACtC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IACvE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9B,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI;CAChB,CAAC;AAEF,MAAM,UAAU,aAAa,CAC3B,MAA+B,EAC/B,KAA8B;IAE9B,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACjE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,KAAK,CAAC,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,0BAA0B,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;YAClF,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,GAAI,CAAC;QAC5D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CACT,SAAS,GAAG,cAAc,KAAK,CAAC,IAAI,SAAS,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAC7C,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IACrC,OAAO,OAAO,CAAC,CAAC;AAClB,CAAC"}
|
|
1
|
+
{"version":3,"file":"propsSchema.js","sourceRoot":"","sources":["../src/propsSchema.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,GAA4C;IAC3D,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ;IACpC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxD,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS;IACtC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IACvE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,UAAU;IACxC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI;CAChB,CAAC;AAEF,MAAM,UAAU,aAAa,CAC3B,MAA+B,EAC/B,KAA8B;IAE9B,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACjE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,KAAK,CAAC,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,0BAA0B,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;YAClF,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,GAAI,CAAC;QAC5D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CACT,SAAS,GAAG,cAAc,KAAK,CAAC,IAAI,SAAS,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAC7C,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IACrC,IAAI,OAAO,CAAC,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC;IAC/C,OAAO,OAAO,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -4,6 +4,13 @@ export interface RuntimeAPI {
|
|
|
4
4
|
DynamicoProvider: React.ComponentType<DynamicoProviderProps>;
|
|
5
5
|
DynamicComponent: React.ComponentType<DynamicComponentProps>;
|
|
6
6
|
useDynamico: (name: string) => RegistryEntry | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Read the merged host scope from inside React. Useful in dynamic
|
|
9
|
+
* components that want to introspect what the host gave them, or to
|
|
10
|
+
* conditionally use scope features (`useScope()['@my/haptics']` may be
|
|
11
|
+
* undefined if the host didn't register it).
|
|
12
|
+
*/
|
|
13
|
+
useScope: () => Scope;
|
|
7
14
|
}
|
|
8
15
|
export interface DynamicoProviderProps {
|
|
9
16
|
source: Source;
|
|
@@ -18,5 +25,20 @@ export interface DynamicComponentProps {
|
|
|
18
25
|
error: DynamicError;
|
|
19
26
|
}> | React.ReactNode;
|
|
20
27
|
}
|
|
21
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Optional renderer-specific knobs passed by the platform package
|
|
30
|
+
* (`@omriashke/dynamico-web`, `@omriashke/dynamico-native`).
|
|
31
|
+
*
|
|
32
|
+
* The web runtime is fine with the built-in `defaultErrorView` (which renders
|
|
33
|
+
* a plain text Fragment via React.createElement), since DOM accepts text
|
|
34
|
+
* nodes anywhere. React Native does NOT — bare strings throw "Text strings
|
|
35
|
+
* must be rendered within a <Text> component". The native package supplies
|
|
36
|
+
* its own `defaultErrorFallback` that wraps the message in `<Text>`.
|
|
37
|
+
*/
|
|
38
|
+
export interface CreateRuntimeOptions {
|
|
39
|
+
defaultErrorFallback?: React.ComponentType<{
|
|
40
|
+
error: DynamicError;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
export declare function createRuntime(defaultScope: Scope, options?: CreateRuntimeOptions): RuntimeAPI;
|
|
22
44
|
//# sourceMappingURL=createRuntime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createRuntime.d.ts","sourceRoot":"","sources":["../../src/react/createRuntime.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAEV,YAAY,EAEZ,aAAa,EACb,KAAK,EACL,MAAM,EACP,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,UAAU;IACzB,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAC7D,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAC7D,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"createRuntime.d.ts","sourceRoot":"","sources":["../../src/react/createRuntime.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAEV,YAAY,EAEZ,aAAa,EACb,KAAK,EACL,MAAM,EACP,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,UAAU;IACzB,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAC7D,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAC7D,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;IACzD;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,KAAK,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;CAChF;AAMD;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,oBAAoB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CACrE;AAED,wBAAgB,aAAa,CAC3B,YAAY,EAAE,KAAK,EACnB,OAAO,GAAE,oBAAyB,GACjC,UAAU,CA+HZ"}
|
|
@@ -2,13 +2,24 @@ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { Registry } from "../registry.js";
|
|
4
4
|
import { validateProps } from "../propsSchema.js";
|
|
5
|
-
export function createRuntime(defaultScope) {
|
|
5
|
+
export function createRuntime(defaultScope, options = {}) {
|
|
6
6
|
const Ctx = React.createContext(null);
|
|
7
|
+
const PlatformDefaultErrorFallback = options.defaultErrorFallback;
|
|
7
8
|
function DynamicoProvider({ source, scope, children }) {
|
|
8
9
|
const registry = React.useMemo(() => {
|
|
9
10
|
const merged = { ...defaultScope, ...(scope ?? {}) };
|
|
10
11
|
return new Registry(source, merged);
|
|
11
12
|
}, [source, scope]);
|
|
13
|
+
// Auto-report host scope to the registry on mount so the server-side
|
|
14
|
+
// test validator can enforce "every component imports something the host
|
|
15
|
+
// actually provides". Source implementations that don't support scope
|
|
16
|
+
// reporting (e.g. local in-memory sources) leave the call as a no-op.
|
|
17
|
+
React.useEffect(() => {
|
|
18
|
+
const merged = { ...defaultScope, ...(scope ?? {}) };
|
|
19
|
+
const keys = Object.keys(merged);
|
|
20
|
+
void source.reportScope?.(keys, "host");
|
|
21
|
+
// Re-run whenever the set of keys changes (added/removed providers).
|
|
22
|
+
}, [source, scope]);
|
|
12
23
|
const value = React.useMemo(() => ({ registry }), [registry]);
|
|
13
24
|
return _jsx(Ctx.Provider, { value: value, children: children });
|
|
14
25
|
}
|
|
@@ -19,6 +30,9 @@ export function createRuntime(defaultScope) {
|
|
|
19
30
|
}
|
|
20
31
|
return ctx.registry;
|
|
21
32
|
}
|
|
33
|
+
function useScope() {
|
|
34
|
+
return useRegistry().getScope();
|
|
35
|
+
}
|
|
22
36
|
function useDynamico(name) {
|
|
23
37
|
const registry = useRegistry();
|
|
24
38
|
const subscribe = React.useCallback((cb) => registry.subscribe(name, cb), [registry, name]);
|
|
@@ -68,7 +82,20 @@ export function createRuntime(defaultScope) {
|
|
|
68
82
|
stack,
|
|
69
83
|
}), renderFallback: (err) => renderError(errorFallback, err), children: React.createElement(Comp, props ?? {}) }, `${name}@${entry.version}`));
|
|
70
84
|
}
|
|
71
|
-
|
|
85
|
+
function renderError(errorFallback, error) {
|
|
86
|
+
if (errorFallback) {
|
|
87
|
+
if (typeof errorFallback === "function") {
|
|
88
|
+
const Fallback = errorFallback;
|
|
89
|
+
return _jsx(Fallback, { error: error });
|
|
90
|
+
}
|
|
91
|
+
return errorFallback;
|
|
92
|
+
}
|
|
93
|
+
if (PlatformDefaultErrorFallback) {
|
|
94
|
+
return _jsx(PlatformDefaultErrorFallback, { error: error });
|
|
95
|
+
}
|
|
96
|
+
return defaultErrorView(error);
|
|
97
|
+
}
|
|
98
|
+
return { DynamicoProvider, DynamicComponent, useDynamico, useScope };
|
|
72
99
|
}
|
|
73
100
|
function pickDefault(factory) {
|
|
74
101
|
if (factory && typeof factory === "object") {
|
|
@@ -82,15 +109,6 @@ function pickDefault(factory) {
|
|
|
82
109
|
return factory;
|
|
83
110
|
return undefined;
|
|
84
111
|
}
|
|
85
|
-
function renderError(errorFallback, error) {
|
|
86
|
-
if (!errorFallback)
|
|
87
|
-
return defaultErrorView(error);
|
|
88
|
-
if (typeof errorFallback === "function") {
|
|
89
|
-
const Fallback = errorFallback;
|
|
90
|
-
return _jsx(Fallback, { error: error });
|
|
91
|
-
}
|
|
92
|
-
return errorFallback;
|
|
93
|
-
}
|
|
94
112
|
function defaultErrorView(error) {
|
|
95
113
|
// Renderer-agnostic: plain text node so it works on both DOM and RN.
|
|
96
114
|
return React.createElement(React.Fragment, null, `[dynamico ${error.kind} error] ${error.name}: ${error.message}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createRuntime.js","sourceRoot":"","sources":["../../src/react/createRuntime.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAS1C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"createRuntime.js","sourceRoot":"","sources":["../../src/react/createRuntime.tsx"],"names":[],"mappings":"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"}
|
package/dist/registry.d.ts
CHANGED
|
@@ -17,6 +17,12 @@ export declare class Registry {
|
|
|
17
17
|
constructor(source: Source, scope: Scope);
|
|
18
18
|
/** Replace or extend the current scope (rare; typically set once). */
|
|
19
19
|
setScope(scope: Scope): void;
|
|
20
|
+
/**
|
|
21
|
+
* Return the merged host scope. Dynamic components reach the same values
|
|
22
|
+
* via `require(name)`, but `getScope()` lets host code (or `useScope()`
|
|
23
|
+
* inside a dynamic component) introspect what's available.
|
|
24
|
+
*/
|
|
25
|
+
getScope(): Scope;
|
|
20
26
|
/** Get the current entry for a name, if any. */
|
|
21
27
|
peek(name: string): RegistryEntry | undefined;
|
|
22
28
|
/**
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,aAAa,EACb,gBAAgB,EAChB,KAAK,EACL,MAAM,EAEP,MAAM,YAAY,CAAC;AAGpB;;;;;;;GAOG;AACH,qBAAa,QAAQ;IAOjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,KAAK;IAPf,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,QAAQ,CAA6C;gBAG1C,MAAM,EAAE,MAAM,EACvB,KAAK,EAAE,KAAK;IAOtB,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI5B,gDAAgD;IAChD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI7C;;;OAGG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAelD,qDAAqD;IACrD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAa/D,kEAAkE;IAClE,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAOpD;;;;;;;;;;;;;OAaG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAezC,OAAO,CAAC,WAAW,CAA8C;IAEjE,OAAO,CAAC,aAAa;IA6CrB;;;OAGG;IACH,OAAO,CAAC,MAAM;IAiDd,OAAO,CAAC,MAAM;CAoBf"}
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,aAAa,EACb,gBAAgB,EAChB,KAAK,EACL,MAAM,EAEP,MAAM,YAAY,CAAC;AAGpB;;;;;;;GAOG;AACH,qBAAa,QAAQ;IAOjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,KAAK;IAPf,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,QAAQ,CAA6C;gBAG1C,MAAM,EAAE,MAAM,EACvB,KAAK,EAAE,KAAK;IAOtB,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI5B;;;;OAIG;IACH,QAAQ,IAAI,KAAK;IAIjB,gDAAgD;IAChD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI7C;;;OAGG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAelD,qDAAqD;IACrD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAa/D,kEAAkE;IAClE,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAOpD;;;;;;;;;;;;;OAaG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAezC,OAAO,CAAC,WAAW,CAA8C;IAEjE,OAAO,CAAC,aAAa;IA6CrB;;;OAGG;IACH,OAAO,CAAC,MAAM;IAiDd,OAAO,CAAC,MAAM;CAoBf"}
|
package/dist/registry.js
CHANGED
|
@@ -24,6 +24,14 @@ export class Registry {
|
|
|
24
24
|
setScope(scope) {
|
|
25
25
|
this.scope = scope;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Return the merged host scope. Dynamic components reach the same values
|
|
29
|
+
* via `require(name)`, but `getScope()` lets host code (or `useScope()`
|
|
30
|
+
* inside a dynamic component) introspect what's available.
|
|
31
|
+
*/
|
|
32
|
+
getScope() {
|
|
33
|
+
return this.scope;
|
|
34
|
+
}
|
|
27
35
|
/** Get the current entry for a name, if any. */
|
|
28
36
|
peek(name) {
|
|
29
37
|
return this.entries.get(name);
|
package/dist/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;GAOG;AACH,MAAM,OAAO,QAAQ;IAMnB,YACmB,MAAc,EACvB,KAAY;QADH,WAAM,GAAN,MAAM,CAAQ;QACvB,UAAK,GAAL,KAAK,CAAO;QAPd,YAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;QAC3C,cAAS,GAAG,IAAI,GAAG,EAAiC,CAAC;QACrD,iBAAY,GAAG,IAAI,GAAG,EAAoB,CAAC;QAC3C,aAAQ,GAAG,IAAI,GAAG,EAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/sources/remote.d.ts
CHANGED
|
@@ -10,6 +10,18 @@ export interface RemoteSourceOptions {
|
|
|
10
10
|
WebSocket?: typeof WebSocket;
|
|
11
11
|
/** Reconnection backoff in ms. Default: 1000. */
|
|
12
12
|
reconnectMs?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Headers to send on every request. Called on each HTTP fetch and on each
|
|
15
|
+
* WebSocket reconnect, so the function can return a freshly-rotated token.
|
|
16
|
+
*
|
|
17
|
+
* - HTTP: merged into the `Authorization: ...` / `x-api-key: ...` request headers.
|
|
18
|
+
* - WebSocket: passed as `new WebSocket(url, undefined, { headers })`. This
|
|
19
|
+
* works on React Native (which extends the standard constructor); browsers
|
|
20
|
+
* silently ignore it because the spec doesn't allow custom WS handshake
|
|
21
|
+
* headers. For browsers behind authenticated reverse proxies, use a
|
|
22
|
+
* query-string token in `wsUrl` or front the registry with cookie auth.
|
|
23
|
+
*/
|
|
24
|
+
headers?: () => Record<string, string>;
|
|
13
25
|
}
|
|
14
26
|
/**
|
|
15
27
|
* Talks to @omriashke/dynamico-registry (or any compatible server).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/sources/remote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,MAAM,EAAgB,MAAM,aAAa,CAAC;AAExE,MAAM,WAAW,mBAAmB;IAClC,kGAAkG;IAClG,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,oFAAoF;IACpF,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;IAC7B,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/sources/remote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,MAAM,EAAgB,MAAM,aAAa,CAAC;AAExE,MAAM,WAAW,mBAAmB;IAClC,kGAAkG;IAClG,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,oFAAoF;IACpF,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;IAC7B,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAuIvE"}
|
package/dist/sources/remote.js
CHANGED
|
@@ -27,7 +27,14 @@ export function createRemoteSource(options) {
|
|
|
27
27
|
if (disposed)
|
|
28
28
|
return;
|
|
29
29
|
try {
|
|
30
|
-
|
|
30
|
+
const hdrs = options.headers?.();
|
|
31
|
+
// RN's WebSocket constructor accepts a third {headers} arg that lets us
|
|
32
|
+
// attach Bearer / x-api-key tokens to the upgrade request. The standard
|
|
33
|
+
// browser WebSocket ignores extra constructor args, so this is a no-op
|
|
34
|
+
// there (use cookies / a query-string token instead).
|
|
35
|
+
socket = hdrs
|
|
36
|
+
? new WSCtor(wsUrl, undefined, { headers: hdrs })
|
|
37
|
+
: new WSCtor(wsUrl);
|
|
31
38
|
}
|
|
32
39
|
catch (err) {
|
|
33
40
|
scheduleReconnect();
|
|
@@ -69,7 +76,10 @@ export function createRemoteSource(options) {
|
|
|
69
76
|
connect();
|
|
70
77
|
return {
|
|
71
78
|
async fetch(name) {
|
|
72
|
-
const
|
|
79
|
+
const init = options.headers
|
|
80
|
+
? { headers: options.headers() }
|
|
81
|
+
: undefined;
|
|
82
|
+
const res = await fetchImpl(`${httpUrl}/component/${encodeURIComponent(name)}`, init);
|
|
73
83
|
if (!res.ok) {
|
|
74
84
|
return {
|
|
75
85
|
name,
|
|
@@ -88,6 +98,28 @@ export function createRemoteSource(options) {
|
|
|
88
98
|
listeners.delete(listener);
|
|
89
99
|
};
|
|
90
100
|
},
|
|
101
|
+
/**
|
|
102
|
+
* Tell the registry what bare specifiers the host's scope exposes. The
|
|
103
|
+
* registry uses this to validate that every component's imports resolve
|
|
104
|
+
* against something the host actually provides — so a typo or a forgotten
|
|
105
|
+
* scope entry is caught at push time, not at navigation time.
|
|
106
|
+
*
|
|
107
|
+
* Best-effort: failures (network, 5xx, server doesn't support /scope) are
|
|
108
|
+
* silently swallowed; they don't block the app from running.
|
|
109
|
+
*/
|
|
110
|
+
async reportScope(keys, reportedBy) {
|
|
111
|
+
try {
|
|
112
|
+
const baseHeaders = options.headers?.() ?? {};
|
|
113
|
+
await fetchImpl(`${httpUrl}/scope`, {
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: { "content-type": "application/json", ...baseHeaders },
|
|
116
|
+
body: JSON.stringify({ keys: [...keys], reportedBy }),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
/* best-effort: never block the host on this */
|
|
121
|
+
}
|
|
122
|
+
},
|
|
91
123
|
dispose() {
|
|
92
124
|
disposed = true;
|
|
93
125
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/sources/remote.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/sources/remote.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
export type Version = string;
|
|
2
2
|
export type Scope = Record<string, unknown>;
|
|
3
3
|
export interface PropsSchemaField {
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Runtime type. `function` validates `typeof v === 'function'` — useful for
|
|
6
|
+
* dynamic screens/components that take callbacks. Function values render
|
|
7
|
+
* fine inside dynamic components; the schema just lets you require them.
|
|
8
|
+
*/
|
|
9
|
+
type: "string" | "number" | "boolean" | "object" | "array" | "function" | "any";
|
|
5
10
|
required?: boolean;
|
|
6
11
|
}
|
|
7
12
|
export type PropsSchema = Record<string, PropsSchemaField>;
|
|
@@ -31,7 +36,7 @@ export interface CompiledModuleError {
|
|
|
31
36
|
version: Version;
|
|
32
37
|
code?: undefined;
|
|
33
38
|
error: {
|
|
34
|
-
kind: "compile" | "typecheck";
|
|
39
|
+
kind: "compile" | "typecheck" | "render" | "test";
|
|
35
40
|
message: string;
|
|
36
41
|
stack?: string;
|
|
37
42
|
diagnostics?: Diagnostic[];
|
|
@@ -76,5 +81,14 @@ export interface Source {
|
|
|
76
81
|
subscribe(listener: (update: SourceUpdate) => void): () => void;
|
|
77
82
|
/** Optional disposal hook. */
|
|
78
83
|
dispose?(): void;
|
|
84
|
+
/**
|
|
85
|
+
* Optional: report the host's scope keys to the registry so the
|
|
86
|
+
* server-side validator knows what bare specifiers it can expect
|
|
87
|
+
* components to import. Called once on DynamicoProvider mount.
|
|
88
|
+
*
|
|
89
|
+
* Remote sources (createRemoteSource) implement this as POST /scope.
|
|
90
|
+
* Local/test sources can leave it undefined.
|
|
91
|
+
*/
|
|
92
|
+
reportScope?(keys: readonly string[], reportedBy?: string): Promise<void>;
|
|
79
93
|
}
|
|
80
94
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omriashke/dynamico-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Renderer-agnostic core for dynamico: source adapters, module loader, versioned component registry.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/react": "^18.3.0",
|
|
41
|
+
"react": "^19.0.0",
|
|
41
42
|
"typescript": "^5.6.3"
|
|
42
43
|
},
|
|
43
44
|
"scripts": {
|
package/src/index.ts
CHANGED
package/src/loader.ts
CHANGED
|
@@ -23,7 +23,10 @@ export function loadModule(
|
|
|
23
23
|
if (name.startsWith("./") || name.startsWith("../") || name.startsWith("/")) {
|
|
24
24
|
return requireRelative(name);
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
// Use `in` (triggers Proxy `has` traps) so that hosts can supply scope
|
|
27
|
+
// via a Proxy and resolve module bindings lazily. Falls back to
|
|
28
|
+
// `hasOwnProperty` semantics for plain object scopes.
|
|
29
|
+
if (name in scope) {
|
|
27
30
|
return scope[name];
|
|
28
31
|
}
|
|
29
32
|
throw new Error(
|
package/src/propsSchema.ts
CHANGED
|
@@ -11,6 +11,7 @@ const TYPE_CHECKS: Record<string, (v: unknown) => boolean> = {
|
|
|
11
11
|
boolean: (v) => typeof v === "boolean",
|
|
12
12
|
object: (v) => typeof v === "object" && v !== null && !Array.isArray(v),
|
|
13
13
|
array: (v) => Array.isArray(v),
|
|
14
|
+
function: (v) => typeof v === "function",
|
|
14
15
|
any: () => true,
|
|
15
16
|
};
|
|
16
17
|
|
|
@@ -39,5 +40,6 @@ export function validateProps(
|
|
|
39
40
|
function describe(v: unknown): string {
|
|
40
41
|
if (v === null) return "null";
|
|
41
42
|
if (Array.isArray(v)) return "array";
|
|
43
|
+
if (typeof v === "function") return "function";
|
|
42
44
|
return typeof v;
|
|
43
45
|
}
|
|
@@ -14,6 +14,13 @@ export interface RuntimeAPI {
|
|
|
14
14
|
DynamicoProvider: React.ComponentType<DynamicoProviderProps>;
|
|
15
15
|
DynamicComponent: React.ComponentType<DynamicComponentProps>;
|
|
16
16
|
useDynamico: (name: string) => RegistryEntry | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Read the merged host scope from inside React. Useful in dynamic
|
|
19
|
+
* components that want to introspect what the host gave them, or to
|
|
20
|
+
* conditionally use scope features (`useScope()['@my/haptics']` may be
|
|
21
|
+
* undefined if the host didn't register it).
|
|
22
|
+
*/
|
|
23
|
+
useScope: () => Scope;
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
export interface DynamicoProviderProps {
|
|
@@ -33,8 +40,26 @@ interface RuntimeContextValue {
|
|
|
33
40
|
registry: Registry;
|
|
34
41
|
}
|
|
35
42
|
|
|
36
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Optional renderer-specific knobs passed by the platform package
|
|
45
|
+
* (`@omriashke/dynamico-web`, `@omriashke/dynamico-native`).
|
|
46
|
+
*
|
|
47
|
+
* The web runtime is fine with the built-in `defaultErrorView` (which renders
|
|
48
|
+
* a plain text Fragment via React.createElement), since DOM accepts text
|
|
49
|
+
* nodes anywhere. React Native does NOT — bare strings throw "Text strings
|
|
50
|
+
* must be rendered within a <Text> component". The native package supplies
|
|
51
|
+
* its own `defaultErrorFallback` that wraps the message in `<Text>`.
|
|
52
|
+
*/
|
|
53
|
+
export interface CreateRuntimeOptions {
|
|
54
|
+
defaultErrorFallback?: React.ComponentType<{ error: DynamicError }>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function createRuntime(
|
|
58
|
+
defaultScope: Scope,
|
|
59
|
+
options: CreateRuntimeOptions = {},
|
|
60
|
+
): RuntimeAPI {
|
|
37
61
|
const Ctx = React.createContext<RuntimeContextValue | null>(null);
|
|
62
|
+
const PlatformDefaultErrorFallback = options.defaultErrorFallback;
|
|
38
63
|
|
|
39
64
|
function DynamicoProvider({ source, scope, children }: DynamicoProviderProps) {
|
|
40
65
|
const registry = React.useMemo(() => {
|
|
@@ -42,6 +67,17 @@ export function createRuntime(defaultScope: Scope): RuntimeAPI {
|
|
|
42
67
|
return new Registry(source, merged);
|
|
43
68
|
}, [source, scope]);
|
|
44
69
|
|
|
70
|
+
// Auto-report host scope to the registry on mount so the server-side
|
|
71
|
+
// test validator can enforce "every component imports something the host
|
|
72
|
+
// actually provides". Source implementations that don't support scope
|
|
73
|
+
// reporting (e.g. local in-memory sources) leave the call as a no-op.
|
|
74
|
+
React.useEffect(() => {
|
|
75
|
+
const merged: Scope = { ...defaultScope, ...(scope ?? {}) };
|
|
76
|
+
const keys = Object.keys(merged);
|
|
77
|
+
void source.reportScope?.(keys, "host");
|
|
78
|
+
// Re-run whenever the set of keys changes (added/removed providers).
|
|
79
|
+
}, [source, scope]);
|
|
80
|
+
|
|
45
81
|
const value = React.useMemo<RuntimeContextValue>(() => ({ registry }), [registry]);
|
|
46
82
|
return <Ctx.Provider value={value}>{children}</Ctx.Provider>;
|
|
47
83
|
}
|
|
@@ -54,6 +90,10 @@ export function createRuntime(defaultScope: Scope): RuntimeAPI {
|
|
|
54
90
|
return ctx.registry;
|
|
55
91
|
}
|
|
56
92
|
|
|
93
|
+
function useScope(): Scope {
|
|
94
|
+
return useRegistry().getScope();
|
|
95
|
+
}
|
|
96
|
+
|
|
57
97
|
function useDynamico(name: string): RegistryEntry | undefined {
|
|
58
98
|
const registry = useRegistry();
|
|
59
99
|
const subscribe = React.useCallback(
|
|
@@ -126,7 +166,24 @@ export function createRuntime(defaultScope: Scope): RuntimeAPI {
|
|
|
126
166
|
);
|
|
127
167
|
}
|
|
128
168
|
|
|
129
|
-
|
|
169
|
+
function renderError(
|
|
170
|
+
errorFallback: DynamicComponentProps["errorFallback"],
|
|
171
|
+
error: DynamicError,
|
|
172
|
+
): React.ReactNode {
|
|
173
|
+
if (errorFallback) {
|
|
174
|
+
if (typeof errorFallback === "function") {
|
|
175
|
+
const Fallback = errorFallback as React.ComponentType<{ error: DynamicError }>;
|
|
176
|
+
return <Fallback error={error} />;
|
|
177
|
+
}
|
|
178
|
+
return errorFallback;
|
|
179
|
+
}
|
|
180
|
+
if (PlatformDefaultErrorFallback) {
|
|
181
|
+
return <PlatformDefaultErrorFallback error={error} />;
|
|
182
|
+
}
|
|
183
|
+
return defaultErrorView(error);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return { DynamicoProvider, DynamicComponent, useDynamico, useScope };
|
|
130
187
|
}
|
|
131
188
|
|
|
132
189
|
function pickDefault(factory: ComponentFactory): unknown {
|
|
@@ -139,18 +196,6 @@ function pickDefault(factory: ComponentFactory): unknown {
|
|
|
139
196
|
return undefined;
|
|
140
197
|
}
|
|
141
198
|
|
|
142
|
-
function renderError(
|
|
143
|
-
errorFallback: DynamicComponentProps["errorFallback"],
|
|
144
|
-
error: DynamicError,
|
|
145
|
-
): React.ReactNode {
|
|
146
|
-
if (!errorFallback) return defaultErrorView(error);
|
|
147
|
-
if (typeof errorFallback === "function") {
|
|
148
|
-
const Fallback = errorFallback as React.ComponentType<{ error: DynamicError }>;
|
|
149
|
-
return <Fallback error={error} />;
|
|
150
|
-
}
|
|
151
|
-
return errorFallback;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
199
|
function defaultErrorView(error: DynamicError): React.ReactElement {
|
|
155
200
|
// Renderer-agnostic: plain text node so it works on both DOM and RN.
|
|
156
201
|
return React.createElement(
|
package/src/registry.ts
CHANGED
|
@@ -37,6 +37,15 @@ export class Registry {
|
|
|
37
37
|
this.scope = scope;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Return the merged host scope. Dynamic components reach the same values
|
|
42
|
+
* via `require(name)`, but `getScope()` lets host code (or `useScope()`
|
|
43
|
+
* inside a dynamic component) introspect what's available.
|
|
44
|
+
*/
|
|
45
|
+
getScope(): Scope {
|
|
46
|
+
return this.scope;
|
|
47
|
+
}
|
|
48
|
+
|
|
40
49
|
/** Get the current entry for a name, if any. */
|
|
41
50
|
peek(name: string): RegistryEntry | undefined {
|
|
42
51
|
return this.entries.get(name);
|
package/src/sources/remote.ts
CHANGED
|
@@ -11,6 +11,18 @@ export interface RemoteSourceOptions {
|
|
|
11
11
|
WebSocket?: typeof WebSocket;
|
|
12
12
|
/** Reconnection backoff in ms. Default: 1000. */
|
|
13
13
|
reconnectMs?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Headers to send on every request. Called on each HTTP fetch and on each
|
|
16
|
+
* WebSocket reconnect, so the function can return a freshly-rotated token.
|
|
17
|
+
*
|
|
18
|
+
* - HTTP: merged into the `Authorization: ...` / `x-api-key: ...` request headers.
|
|
19
|
+
* - WebSocket: passed as `new WebSocket(url, undefined, { headers })`. This
|
|
20
|
+
* works on React Native (which extends the standard constructor); browsers
|
|
21
|
+
* silently ignore it because the spec doesn't allow custom WS handshake
|
|
22
|
+
* headers. For browsers behind authenticated reverse proxies, use a
|
|
23
|
+
* query-string token in `wsUrl` or front the registry with cookie auth.
|
|
24
|
+
*/
|
|
25
|
+
headers?: () => Record<string, string>;
|
|
14
26
|
}
|
|
15
27
|
|
|
16
28
|
/**
|
|
@@ -47,7 +59,18 @@ export function createRemoteSource(options: RemoteSourceOptions): Source {
|
|
|
47
59
|
function connect(): void {
|
|
48
60
|
if (disposed) return;
|
|
49
61
|
try {
|
|
50
|
-
|
|
62
|
+
const hdrs = options.headers?.();
|
|
63
|
+
// RN's WebSocket constructor accepts a third {headers} arg that lets us
|
|
64
|
+
// attach Bearer / x-api-key tokens to the upgrade request. The standard
|
|
65
|
+
// browser WebSocket ignores extra constructor args, so this is a no-op
|
|
66
|
+
// there (use cookies / a query-string token instead).
|
|
67
|
+
socket = hdrs
|
|
68
|
+
? new (WSCtor as unknown as new (
|
|
69
|
+
url: string,
|
|
70
|
+
protocols?: string | string[],
|
|
71
|
+
options?: { headers?: Record<string, string> },
|
|
72
|
+
) => WebSocket)(wsUrl, undefined, { headers: hdrs })
|
|
73
|
+
: new WSCtor(wsUrl);
|
|
51
74
|
} catch (err) {
|
|
52
75
|
scheduleReconnect();
|
|
53
76
|
return;
|
|
@@ -88,7 +111,13 @@ export function createRemoteSource(options: RemoteSourceOptions): Source {
|
|
|
88
111
|
|
|
89
112
|
return {
|
|
90
113
|
async fetch(name: string): Promise<CompiledModule> {
|
|
91
|
-
const
|
|
114
|
+
const init: RequestInit | undefined = options.headers
|
|
115
|
+
? { headers: options.headers() }
|
|
116
|
+
: undefined;
|
|
117
|
+
const res = await fetchImpl(
|
|
118
|
+
`${httpUrl}/component/${encodeURIComponent(name)}`,
|
|
119
|
+
init,
|
|
120
|
+
);
|
|
92
121
|
if (!res.ok) {
|
|
93
122
|
return {
|
|
94
123
|
name,
|
|
@@ -107,6 +136,27 @@ export function createRemoteSource(options: RemoteSourceOptions): Source {
|
|
|
107
136
|
listeners.delete(listener);
|
|
108
137
|
};
|
|
109
138
|
},
|
|
139
|
+
/**
|
|
140
|
+
* Tell the registry what bare specifiers the host's scope exposes. The
|
|
141
|
+
* registry uses this to validate that every component's imports resolve
|
|
142
|
+
* against something the host actually provides — so a typo or a forgotten
|
|
143
|
+
* scope entry is caught at push time, not at navigation time.
|
|
144
|
+
*
|
|
145
|
+
* Best-effort: failures (network, 5xx, server doesn't support /scope) are
|
|
146
|
+
* silently swallowed; they don't block the app from running.
|
|
147
|
+
*/
|
|
148
|
+
async reportScope(keys, reportedBy) {
|
|
149
|
+
try {
|
|
150
|
+
const baseHeaders = options.headers?.() ?? {};
|
|
151
|
+
await fetchImpl(`${httpUrl}/scope`, {
|
|
152
|
+
method: "POST",
|
|
153
|
+
headers: { "content-type": "application/json", ...baseHeaders },
|
|
154
|
+
body: JSON.stringify({ keys: [...keys], reportedBy }),
|
|
155
|
+
});
|
|
156
|
+
} catch {
|
|
157
|
+
/* best-effort: never block the host on this */
|
|
158
|
+
}
|
|
159
|
+
},
|
|
110
160
|
dispose() {
|
|
111
161
|
disposed = true;
|
|
112
162
|
try {
|
package/src/types.ts
CHANGED
|
@@ -3,7 +3,19 @@ export type Version = string;
|
|
|
3
3
|
export type Scope = Record<string, unknown>;
|
|
4
4
|
|
|
5
5
|
export interface PropsSchemaField {
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Runtime type. `function` validates `typeof v === 'function'` — useful for
|
|
8
|
+
* dynamic screens/components that take callbacks. Function values render
|
|
9
|
+
* fine inside dynamic components; the schema just lets you require them.
|
|
10
|
+
*/
|
|
11
|
+
type:
|
|
12
|
+
| "string"
|
|
13
|
+
| "number"
|
|
14
|
+
| "boolean"
|
|
15
|
+
| "object"
|
|
16
|
+
| "array"
|
|
17
|
+
| "function"
|
|
18
|
+
| "any";
|
|
7
19
|
required?: boolean;
|
|
8
20
|
}
|
|
9
21
|
|
|
@@ -37,7 +49,7 @@ export interface CompiledModuleError {
|
|
|
37
49
|
version: Version;
|
|
38
50
|
code?: undefined;
|
|
39
51
|
error: {
|
|
40
|
-
kind: "compile" | "typecheck";
|
|
52
|
+
kind: "compile" | "typecheck" | "render" | "test";
|
|
41
53
|
message: string;
|
|
42
54
|
stack?: string;
|
|
43
55
|
diagnostics?: Diagnostic[];
|
|
@@ -93,4 +105,13 @@ export interface Source {
|
|
|
93
105
|
subscribe(listener: (update: SourceUpdate) => void): () => void;
|
|
94
106
|
/** Optional disposal hook. */
|
|
95
107
|
dispose?(): void;
|
|
108
|
+
/**
|
|
109
|
+
* Optional: report the host's scope keys to the registry so the
|
|
110
|
+
* server-side validator knows what bare specifiers it can expect
|
|
111
|
+
* components to import. Called once on DynamicoProvider mount.
|
|
112
|
+
*
|
|
113
|
+
* Remote sources (createRemoteSource) implement this as POST /scope.
|
|
114
|
+
* Local/test sources can leave it undefined.
|
|
115
|
+
*/
|
|
116
|
+
reportScope?(keys: readonly string[], reportedBy?: string): Promise<void>;
|
|
96
117
|
}
|