@assistant-ui/metro 0.0.8 → 0.0.10
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.cjs +13 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/transformer.cjs +22 -7
- package/dist/transformer.cjs.map +1 -1
- package/dist/transformer.d.cts.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +28 -3
- package/src/transformer.ts +5 -2
package/dist/index.cjs
CHANGED
|
@@ -8,6 +8,11 @@ const require$1 = (0, require("node:module").createRequire)(require("url").pathT
|
|
|
8
8
|
*/
|
|
9
9
|
const UPSTREAM_TRANSFORMER_ENV = "AUI_METRO_UPSTREAM_TRANSFORMER";
|
|
10
10
|
/**
|
|
11
|
+
* Env var carrying the `backendless` option to the transformer. Metro forks its
|
|
12
|
+
* transform workers after `metro.config` is evaluated, so they inherit it.
|
|
13
|
+
*/
|
|
14
|
+
const BACKENDLESS_ENV = "AUI_METRO_BACKENDLESS";
|
|
15
|
+
/**
|
|
11
16
|
* Wraps a Metro (or Expo) config so assistant-ui `"use generative"` modules are
|
|
12
17
|
* compiled. Such a file colocates a tool's schema, its `execute`, and its
|
|
13
18
|
* `render` via {@link https://www.assistant-ui.com/docs/tools/defining-tools | defineToolkit}.
|
|
@@ -23,7 +28,10 @@ const UPSTREAM_TRANSFORMER_ENV = "AUI_METRO_UPSTREAM_TRANSFORMER";
|
|
|
23
28
|
* const { getDefaultConfig } = require("expo/metro-config");
|
|
24
29
|
* const { withAui } = require("@assistant-ui/metro");
|
|
25
30
|
*
|
|
26
|
-
* module.exports = withAui(
|
|
31
|
+
* module.exports = withAui({
|
|
32
|
+
* ...getDefaultConfig(__dirname),
|
|
33
|
+
* aui: { backendless: true },
|
|
34
|
+
* });
|
|
27
35
|
* ```
|
|
28
36
|
*
|
|
29
37
|
* Authoring is identical to the web: a `"use generative"` file whose default
|
|
@@ -31,10 +39,12 @@ const UPSTREAM_TRANSFORMER_ENV = "AUI_METRO_UPSTREAM_TRANSFORMER";
|
|
|
31
39
|
*/
|
|
32
40
|
function withAui(config) {
|
|
33
41
|
const self = require$1.resolve("@assistant-ui/metro/transformer");
|
|
42
|
+
const { aui, ...baseConfig } = config;
|
|
34
43
|
const upstream = config.transformer?.babelTransformerPath;
|
|
44
|
+
if (aui?.backendless) process.env[BACKENDLESS_ENV] = "1";
|
|
35
45
|
if (upstream && upstream !== self) process.env[UPSTREAM_TRANSFORMER_ENV] = upstream;
|
|
36
46
|
return {
|
|
37
|
-
...
|
|
47
|
+
...baseConfig,
|
|
38
48
|
transformer: {
|
|
39
49
|
...config.transformer,
|
|
40
50
|
babelTransformerPath: self
|
|
@@ -42,6 +52,7 @@ function withAui(config) {
|
|
|
42
52
|
};
|
|
43
53
|
}
|
|
44
54
|
//#endregion
|
|
55
|
+
exports.BACKENDLESS_ENV = BACKENDLESS_ENV;
|
|
45
56
|
exports.UPSTREAM_TRANSFORMER_ENV = UPSTREAM_TRANSFORMER_ENV;
|
|
46
57
|
exports.withAui = withAui;
|
|
47
58
|
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["require","createRequire"],"sources":["../src/index.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\n\n/**\n * The shape of a Metro / Expo config `withAui` accepts. Typed loosely so this\n * package needs no hard dependency on `metro` or `expo`; the input shape is\n * preserved and only `transformer.babelTransformerPath` is augmented.\n */\nexport type MetroConfigLike = {\n transformer?:\n | {\n babelTransformerPath?: string | undefined;\n [key: string]: unknown;\n }\n | undefined;\n [key: string]: unknown;\n};\n\n/**\n * Env var the transformer reads to delegate to the project's existing\n * (Expo / React Native) babel transformer. Metro forks its transform workers\n * after `metro.config` is evaluated, so they inherit this value.\n */\nexport const UPSTREAM_TRANSFORMER_ENV = \"AUI_METRO_UPSTREAM_TRANSFORMER\";\n\n/**\n * Wraps a Metro (or Expo) config so assistant-ui `\"use generative\"` modules are\n * compiled. Such a file colocates a tool's schema, its `execute`, and its\n * `render` via {@link https://www.assistant-ui.com/docs/tools/defining-tools | defineToolkit}.\n *\n * It points Metro's `babelTransformerPath` at this package's transformer, which\n * runs the `\"use generative\"` compiler and then delegates to your project's\n * existing transformer. The device (client) build keeps each tool's `render`\n * and any frontend `execute`; a server build (an Expo Router `+api` route)\n * keeps a server `execute` instead.\n *\n * ```js\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withAui } = require(\"@assistant-ui/metro\");\n *\n * module.exports = withAui(getDefaultConfig(__dirname));\n * ```\n *\n * Authoring is identical to the web: a `\"use generative\"` file whose default\n * export is `defineToolkit({ ... })`, registered with `Tools({ toolkit })`.\n */\nexport function withAui<T extends MetroConfigLike>(config: T): T {\n const self = require.resolve(\"@assistant-ui/metro/transformer\");\n const upstream = config.transformer?.babelTransformerPath;\n\n // Guard against a double-wrap (`withAui(withAui(config))`, or a shared config\n // already wrapped): if it already points at our transformer, keep the real\n // upstream captured earlier rather than overwriting it with our own path,\n // which would make `resolveUpstream()` return this transformer and recurse.\n if (upstream && upstream !== self) {\n process.env[UPSTREAM_TRANSFORMER_ENV] = upstream;\n }\n\n return {\n ...
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["require","createRequire"],"sources":["../src/index.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\n\n/**\n * The shape of a Metro / Expo config `withAui` accepts. Typed loosely so this\n * package needs no hard dependency on `metro` or `expo`; the input shape is\n * preserved and only `transformer.babelTransformerPath` is augmented.\n */\nexport type MetroConfigLike = {\n /** assistant-ui options, stripped from the config handed back to Metro. */\n aui?: WithAuiOptions | undefined;\n transformer?:\n | {\n babelTransformerPath?: string | undefined;\n [key: string]: unknown;\n }\n | undefined;\n [key: string]: unknown;\n};\n\n/**\n * Env var the transformer reads to delegate to the project's existing\n * (Expo / React Native) babel transformer. Metro forks its transform workers\n * after `metro.config` is evaluated, so they inherit this value.\n */\nexport const UPSTREAM_TRANSFORMER_ENV = \"AUI_METRO_UPSTREAM_TRANSFORMER\";\n\n/**\n * Env var carrying the `backendless` option to the transformer. Metro forks its\n * transform workers after `metro.config` is evaluated, so they inherit it.\n */\nexport const BACKENDLESS_ENV = \"AUI_METRO_BACKENDLESS\";\n\nexport interface WithAuiOptions {\n /**\n * The app has no backend importing the server builds of its `\"use generative\"`\n * modules (e.g. cloud-hosted runs). Frontend/human tool schemas then stay\n * uploadable from the client instead of being assumed backend-known.\n */\n backendless?: boolean;\n}\n\n/**\n * Wraps a Metro (or Expo) config so assistant-ui `\"use generative\"` modules are\n * compiled. Such a file colocates a tool's schema, its `execute`, and its\n * `render` via {@link https://www.assistant-ui.com/docs/tools/defining-tools | defineToolkit}.\n *\n * It points Metro's `babelTransformerPath` at this package's transformer, which\n * runs the `\"use generative\"` compiler and then delegates to your project's\n * existing transformer. The device (client) build keeps each tool's `render`\n * and any frontend `execute`; a server build (an Expo Router `+api` route)\n * keeps a server `execute` instead.\n *\n * ```js\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withAui } = require(\"@assistant-ui/metro\");\n *\n * module.exports = withAui({\n * ...getDefaultConfig(__dirname),\n * aui: { backendless: true },\n * });\n * ```\n *\n * Authoring is identical to the web: a `\"use generative\"` file whose default\n * export is `defineToolkit({ ... })`, registered with `Tools({ toolkit })`.\n */\nexport function withAui<T extends MetroConfigLike>(config: T): T {\n const self = require.resolve(\"@assistant-ui/metro/transformer\");\n // Metro validates config keys it does not recognize, so `aui` must not\n // survive into the returned config.\n const { aui, ...baseConfig } = config;\n const upstream = config.transformer?.babelTransformerPath;\n\n if (aui?.backendless) process.env[BACKENDLESS_ENV] = \"1\";\n\n // Guard against a double-wrap (`withAui(withAui(config))`, or a shared config\n // already wrapped): if it already points at our transformer, keep the real\n // upstream captured earlier rather than overwriting it with our own path,\n // which would make `resolveUpstream()` return this transformer and recurse.\n if (upstream && upstream !== self) {\n process.env[UPSTREAM_TRANSFORMER_ENV] = upstream;\n }\n\n return {\n ...baseConfig,\n transformer: {\n ...config.transformer,\n babelTransformerPath: self,\n },\n } as T;\n}\n"],"mappings":";;AAEA,MAAMA,aAAAA,wBAAUC,CAAAA,CAAAA,cAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,IAA6B;;;;;;AAwB7C,MAAa,2BAA2B;;;;;AAMxC,MAAa,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;AAoC/B,SAAgB,QAAmC,QAAc;CAC/D,MAAM,OAAOD,UAAQ,QAAQ,iCAAiC;CAG9D,MAAM,EAAE,KAAK,GAAG,eAAe;CAC/B,MAAM,WAAW,OAAO,aAAa;CAErC,IAAI,KAAK,aAAa,QAAQ,IAAI,mBAAmB;CAMrD,IAAI,YAAY,aAAa,MAC3B,QAAQ,IAAI,4BAA4B;CAG1C,OAAO;EACL,GAAG;EACH,aAAa;GACX,GAAG,OAAO;GACV,sBAAsB;EACxB;CACF;AACF"}
|
package/dist/index.d.cts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* preserved and only `transformer.babelTransformerPath` is augmented.
|
|
6
6
|
*/
|
|
7
7
|
type MetroConfigLike = {
|
|
8
|
+
/** assistant-ui options, stripped from the config handed back to Metro. */
|
|
9
|
+
aui?: WithAuiOptions | undefined;
|
|
8
10
|
transformer?: {
|
|
9
11
|
babelTransformerPath?: string | undefined;
|
|
10
12
|
[key: string]: unknown;
|
|
@@ -17,6 +19,19 @@ type MetroConfigLike = {
|
|
|
17
19
|
* after `metro.config` is evaluated, so they inherit this value.
|
|
18
20
|
*/
|
|
19
21
|
declare const UPSTREAM_TRANSFORMER_ENV = "AUI_METRO_UPSTREAM_TRANSFORMER";
|
|
22
|
+
/**
|
|
23
|
+
* Env var carrying the `backendless` option to the transformer. Metro forks its
|
|
24
|
+
* transform workers after `metro.config` is evaluated, so they inherit it.
|
|
25
|
+
*/
|
|
26
|
+
declare const BACKENDLESS_ENV = "AUI_METRO_BACKENDLESS";
|
|
27
|
+
interface WithAuiOptions {
|
|
28
|
+
/**
|
|
29
|
+
* The app has no backend importing the server builds of its `"use generative"`
|
|
30
|
+
* modules (e.g. cloud-hosted runs). Frontend/human tool schemas then stay
|
|
31
|
+
* uploadable from the client instead of being assumed backend-known.
|
|
32
|
+
*/
|
|
33
|
+
backendless?: boolean;
|
|
34
|
+
}
|
|
20
35
|
/**
|
|
21
36
|
* Wraps a Metro (or Expo) config so assistant-ui `"use generative"` modules are
|
|
22
37
|
* compiled. Such a file colocates a tool's schema, its `execute`, and its
|
|
@@ -33,7 +48,10 @@ declare const UPSTREAM_TRANSFORMER_ENV = "AUI_METRO_UPSTREAM_TRANSFORMER";
|
|
|
33
48
|
* const { getDefaultConfig } = require("expo/metro-config");
|
|
34
49
|
* const { withAui } = require("@assistant-ui/metro");
|
|
35
50
|
*
|
|
36
|
-
* module.exports = withAui(
|
|
51
|
+
* module.exports = withAui({
|
|
52
|
+
* ...getDefaultConfig(__dirname),
|
|
53
|
+
* aui: { backendless: true },
|
|
54
|
+
* });
|
|
37
55
|
* ```
|
|
38
56
|
*
|
|
39
57
|
* Authoring is identical to the web: a `"use generative"` file whose default
|
|
@@ -41,5 +59,5 @@ declare const UPSTREAM_TRANSFORMER_ENV = "AUI_METRO_UPSTREAM_TRANSFORMER";
|
|
|
41
59
|
*/
|
|
42
60
|
declare function withAui<T extends MetroConfigLike>(config: T): T;
|
|
43
61
|
//#endregion
|
|
44
|
-
export { MetroConfigLike, UPSTREAM_TRANSFORMER_ENV, withAui };
|
|
62
|
+
export { BACKENDLESS_ENV, MetroConfigLike, UPSTREAM_TRANSFORMER_ENV, WithAuiOptions, withAui };
|
|
45
63
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;KASY;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;KASY;;EAEV,MAAM;EACN;IAEM;KACC;;GAGN;;;;;;;cAQU;;;;;cAMA;UAEI;;;;;;EAMf;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4Bc,QAAQ,UAAU,iBAAiB,QAAQ,IAAI"}
|
package/dist/transformer.cjs
CHANGED
|
@@ -40,7 +40,7 @@ _babel_types = __toESM(_babel_types, 1);
|
|
|
40
40
|
const DIRECTIVE = "use generative";
|
|
41
41
|
//#endregion
|
|
42
42
|
//#region ../x-generative-compiler/dist/package.js
|
|
43
|
-
var version = "0.0.
|
|
43
|
+
var version = "0.0.14";
|
|
44
44
|
//#endregion
|
|
45
45
|
//#region ../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/constants.js
|
|
46
46
|
var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -1590,6 +1590,7 @@ function isLineTerminator(char) {
|
|
|
1590
1590
|
*/
|
|
1591
1591
|
function compileGenerative(code, options) {
|
|
1592
1592
|
const { target, filename } = options;
|
|
1593
|
+
const backendless = options.backendless ?? false;
|
|
1593
1594
|
const ast = (0, _babel_parser.parse)(code, {
|
|
1594
1595
|
sourceType: "module",
|
|
1595
1596
|
plugins: parserPlugins
|
|
@@ -1616,7 +1617,7 @@ function compileGenerative(code, options) {
|
|
|
1616
1617
|
}
|
|
1617
1618
|
if (_babel_types.isIdentifier(callee, { name: TOOLKIT_WRAPPER })) {
|
|
1618
1619
|
if (!object) throw new GenerativeCompileError(`${TOOLKIT_WRAPPER}() takes an inline object literal of tools`, filename);
|
|
1619
|
-
compileToolkit(object, target, generativeInstances, interactableToolImports, toolkitSpreadNames, namespaceImports, flags, filename);
|
|
1620
|
+
compileToolkit(object, target, generativeInstances, interactableToolImports, toolkitSpreadNames, namespaceImports, flags, backendless, filename);
|
|
1620
1621
|
path.replaceWith(object);
|
|
1621
1622
|
path.skip();
|
|
1622
1623
|
}
|
|
@@ -1777,6 +1778,15 @@ function collectGenerativeInstances(ast) {
|
|
|
1777
1778
|
}
|
|
1778
1779
|
return names;
|
|
1779
1780
|
}
|
|
1781
|
+
/**
|
|
1782
|
+
* Wraps a pass-through generative entry (`generative.present()`) so the tool it
|
|
1783
|
+
* returns loses its `unstable_backendDefault` marker. The library stamps the
|
|
1784
|
+
* marker at runtime, out of this compiler's reach, so a backendless client
|
|
1785
|
+
* build strips it post-hoc instead of threading an option into the library.
|
|
1786
|
+
*/
|
|
1787
|
+
function stripBackendDefaultExpression(expr) {
|
|
1788
|
+
return _babel_types.callExpression(_babel_types.arrowFunctionExpression([_babel_types.objectPattern([_babel_types.objectProperty(_babel_types.identifier("unstable_backendDefault"), _babel_types.identifier("_backendDefault")), _babel_types.restElement(_babel_types.identifier("tool"))])], _babel_types.identifier("tool")), [expr]);
|
|
1789
|
+
}
|
|
1780
1790
|
function collectGenerativeFactoryImports(ast) {
|
|
1781
1791
|
const names = /* @__PURE__ */ new Set();
|
|
1782
1792
|
for (const statement of ast.program.body) {
|
|
@@ -2191,7 +2201,7 @@ function compileComponents(object, target, flags, filename) {
|
|
|
2191
2201
|
* `generative.present()` passes through, the library having already split it.
|
|
2192
2202
|
* Mutates the object in place and records outcomes in {@link TargetFlags}.
|
|
2193
2203
|
*/
|
|
2194
|
-
function compileToolkit(object, target, instances, interactableToolImports, toolkitSpreadNames, namespaceImports, flags, filename) {
|
|
2204
|
+
function compileToolkit(object, target, instances, interactableToolImports, toolkitSpreadNames, namespaceImports, flags, backendless, filename) {
|
|
2195
2205
|
if (target === "client") warnDuplicateToolkitNames(object, toolkitSpreadNames, filename);
|
|
2196
2206
|
const nextProperties = [];
|
|
2197
2207
|
for (const entry of object.properties) {
|
|
@@ -2203,6 +2213,7 @@ function compileToolkit(object, target, instances, interactableToolImports, tool
|
|
|
2203
2213
|
}
|
|
2204
2214
|
const raw = entryRawValue(entry);
|
|
2205
2215
|
if (raw && isGenerativeToolEntry(raw, instances)) {
|
|
2216
|
+
if (backendless && target === "client" && _babel_types.isObjectProperty(entry)) entry.value = stripBackendDefaultExpression(raw);
|
|
2206
2217
|
nextProperties.push(entry);
|
|
2207
2218
|
continue;
|
|
2208
2219
|
}
|
|
@@ -2247,7 +2258,7 @@ function compileToolkit(object, target, instances, interactableToolImports, tool
|
|
|
2247
2258
|
}
|
|
2248
2259
|
}
|
|
2249
2260
|
setToolType(value, type);
|
|
2250
|
-
setBackendDefault(value, target, type);
|
|
2261
|
+
setBackendDefault(value, target, type, backendless);
|
|
2251
2262
|
nextProperties.push(entry);
|
|
2252
2263
|
}
|
|
2253
2264
|
object.properties = nextProperties;
|
|
@@ -2358,8 +2369,9 @@ function setToolType(object, type) {
|
|
|
2358
2369
|
removeMember(object, "type");
|
|
2359
2370
|
object.properties.push(_babel_types.objectProperty(_babel_types.identifier("type"), _babel_types.stringLiteral(type)));
|
|
2360
2371
|
}
|
|
2361
|
-
function setBackendDefault(object, target, type) {
|
|
2372
|
+
function setBackendDefault(object, target, type, backendless) {
|
|
2362
2373
|
removeMember(object, "unstable_backendDefault");
|
|
2374
|
+
if (backendless) return;
|
|
2363
2375
|
if (target !== "client" || type !== "frontend" && type !== "human") return;
|
|
2364
2376
|
object.properties.push(_babel_types.objectProperty(_babel_types.identifier("unstable_backendDefault"), _babel_types.objectExpression([_babel_types.objectProperty(_babel_types.identifier("parameters"), _babel_types.booleanLiteral(true))])));
|
|
2365
2377
|
}
|
|
@@ -2473,7 +2485,8 @@ function transform(props) {
|
|
|
2473
2485
|
const { code } = compileGenerative(src, {
|
|
2474
2486
|
target: isServerEnvironment(options?.customTransformOptions?.environment) ? "server" : "client",
|
|
2475
2487
|
filename,
|
|
2476
|
-
injectServerOnly: false
|
|
2488
|
+
injectServerOnly: false,
|
|
2489
|
+
backendless: process.env[require_index.BACKENDLESS_ENV] === "1"
|
|
2477
2490
|
});
|
|
2478
2491
|
return upstream.transform({
|
|
2479
2492
|
...props,
|
|
@@ -2494,7 +2507,9 @@ function selfCacheToken() {
|
|
|
2494
2507
|
}
|
|
2495
2508
|
function getCacheKey() {
|
|
2496
2509
|
const upstream = upstreamTransformer();
|
|
2497
|
-
|
|
2510
|
+
const base = upstream.getCacheKey ? upstream.getCacheKey() : "";
|
|
2511
|
+
const backendless = process.env["AUI_METRO_BACKENDLESS"] === "1" ? ":backendless" : "";
|
|
2512
|
+
return `${base}$aui-metro:${selfCacheToken()}${backendless}`;
|
|
2498
2513
|
}
|
|
2499
2514
|
//#endregion
|
|
2500
2515
|
exports.getCacheKey = getCacheKey;
|