@assistant-ui/metro 0.0.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/LICENSE +21 -0
- package/README.md +89 -0
- package/dist/index.cjs +48 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +45 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/transformer.cjs +2189 -0
- package/dist/transformer.cjs.map +1 -0
- package/dist/transformer.d.cts +21 -0
- package/dist/transformer.d.cts.map +1 -0
- package/package.json +64 -0
- package/src/__fixtures__/mock-upstream.cjs +10 -0
- package/src/index.ts +68 -0
- package/src/transformer.test.ts +101 -0
- package/src/transformer.ts +116 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 AgentbaseAI Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @assistant-ui/metro
|
|
2
|
+
|
|
3
|
+
Metro / Expo integration for [assistant-ui](https://www.assistant-ui.com): the
|
|
4
|
+
`"use generative"` directive compiler for React Native. It lets you author tools
|
|
5
|
+
with the **same** [`defineToolkit`](https://www.assistant-ui.com/docs/tools/defining-tools)
|
|
6
|
+
API as on the web: one file colocating a tool's schema, its `execute`, and its
|
|
7
|
+
`render`, then compiles them for the device (and any Expo Router server route).
|
|
8
|
+
|
|
9
|
+
Works with **Expo** and **bare React Native** (both bundle with Metro).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install --save-dev @assistant-ui/metro
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
Wrap your Metro config with `withAui`:
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
// metro.config.js
|
|
23
|
+
const { getDefaultConfig } = require("expo/metro-config");
|
|
24
|
+
const { withAui } = require("@assistant-ui/metro");
|
|
25
|
+
|
|
26
|
+
const config = getDefaultConfig(__dirname);
|
|
27
|
+
|
|
28
|
+
module.exports = withAui(config);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Bare React Native (without Expo):
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
// metro.config.js
|
|
35
|
+
const { getDefaultConfig } = require("@react-native/metro-config");
|
|
36
|
+
const { withAui } = require("@assistant-ui/metro");
|
|
37
|
+
|
|
38
|
+
module.exports = withAui(getDefaultConfig(__dirname));
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
Author a `"use generative"` toolkit exactly like on the web, importing
|
|
44
|
+
`defineToolkit` from `@assistant-ui/react-native`:
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
// toolkit.tsx
|
|
48
|
+
"use generative";
|
|
49
|
+
|
|
50
|
+
import { defineToolkit } from "@assistant-ui/react-native";
|
|
51
|
+
import { z } from "zod";
|
|
52
|
+
import { WeatherCard } from "./WeatherCard";
|
|
53
|
+
|
|
54
|
+
export default defineToolkit({
|
|
55
|
+
get_weather: {
|
|
56
|
+
description: "Get the weather for a city.",
|
|
57
|
+
parameters: z.object({ city: z.string() }),
|
|
58
|
+
execute: async ({ city }) => {
|
|
59
|
+
"use client";
|
|
60
|
+
return fetchWeather(city);
|
|
61
|
+
},
|
|
62
|
+
render: ({ args, result }) => <WeatherCard city={args.city} weather={result} />,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Register it with `Tools({ toolkit })`, the same as on the web:
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { Tools, useAui } from "@assistant-ui/react-native";
|
|
71
|
+
import toolkit from "./toolkit";
|
|
72
|
+
|
|
73
|
+
const aui = useAui({ tools: Tools({ toolkit }) });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## How it works
|
|
77
|
+
|
|
78
|
+
`withAui` points Metro's `babelTransformerPath` at this package's transformer,
|
|
79
|
+
which runs the `"use generative"` compiler and then delegates to your project's
|
|
80
|
+
existing transformer (Expo's or React Native's).
|
|
81
|
+
|
|
82
|
+
The build target follows Metro's environment: the device app gets the **client**
|
|
83
|
+
build (schema + `render` + frontend `execute`), while an Expo Router `+api`
|
|
84
|
+
route (bundled for a server environment) gets the **server** build (schema +
|
|
85
|
+
backend `execute`). This mirrors [`@assistant-ui/next`](https://www.assistant-ui.com/docs/tools/defining-tools)
|
|
86
|
+
and `@assistant-ui/vite`.
|
|
87
|
+
|
|
88
|
+
See the [Tools docs](https://www.assistant-ui.com/docs/tools/defining-tools) for
|
|
89
|
+
the full authoring API.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/index.ts
|
|
3
|
+
const require$1 = (0, require("node:module").createRequire)(require("url").pathToFileURL(__filename).href);
|
|
4
|
+
/**
|
|
5
|
+
* Env var the transformer reads to delegate to the project's existing
|
|
6
|
+
* (Expo / React Native) babel transformer. Metro forks its transform workers
|
|
7
|
+
* after `metro.config` is evaluated, so they inherit this value.
|
|
8
|
+
*/
|
|
9
|
+
const UPSTREAM_TRANSFORMER_ENV = "AUI_METRO_UPSTREAM_TRANSFORMER";
|
|
10
|
+
/**
|
|
11
|
+
* Wraps a Metro (or Expo) config so assistant-ui `"use generative"` modules are
|
|
12
|
+
* compiled. Such a file colocates a tool's schema, its `execute`, and its
|
|
13
|
+
* `render` via {@link https://www.assistant-ui.com/docs/tools/defining-tools | defineToolkit}.
|
|
14
|
+
*
|
|
15
|
+
* It points Metro's `babelTransformerPath` at this package's transformer, which
|
|
16
|
+
* runs the `"use generative"` compiler and then delegates to your project's
|
|
17
|
+
* existing transformer. The device (client) build keeps each tool's `render`
|
|
18
|
+
* and any frontend `execute`; a server build (an Expo Router `+api` route)
|
|
19
|
+
* keeps a server `execute` instead.
|
|
20
|
+
*
|
|
21
|
+
* ```js
|
|
22
|
+
* // metro.config.js
|
|
23
|
+
* const { getDefaultConfig } = require("expo/metro-config");
|
|
24
|
+
* const { withAui } = require("@assistant-ui/metro");
|
|
25
|
+
*
|
|
26
|
+
* module.exports = withAui(getDefaultConfig(__dirname));
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* Authoring is identical to the web: a `"use generative"` file whose default
|
|
30
|
+
* export is `defineToolkit({ ... })`, registered with `Tools({ toolkit })`.
|
|
31
|
+
*/
|
|
32
|
+
function withAui(config) {
|
|
33
|
+
const self = require$1.resolve("@assistant-ui/metro/transformer");
|
|
34
|
+
const upstream = config.transformer?.babelTransformerPath;
|
|
35
|
+
if (upstream && upstream !== self) process.env[UPSTREAM_TRANSFORMER_ENV] = upstream;
|
|
36
|
+
return {
|
|
37
|
+
...config,
|
|
38
|
+
transformer: {
|
|
39
|
+
...config.transformer,
|
|
40
|
+
babelTransformerPath: self
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
exports.UPSTREAM_TRANSFORMER_ENV = UPSTREAM_TRANSFORMER_ENV;
|
|
46
|
+
exports.withAui = withAui;
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["require"],"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 ...config,\n transformer: {\n ...config.transformer,\n babelTransformerPath: self,\n },\n };\n}\n"],"mappings":";;AAEA,MAAMA,aAAAA,wBAAAA,EAAAA,eAAAA,QAAAA,KAAAA,EAAAA,cAAAA,UAAAA,EAAAA,IAAuC;;;;;;AAsB7C,MAAa,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;AAwBxC,SAAgB,QAAmC,QAAc;CAC/D,MAAM,OAAOA,UAAQ,QAAQ,iCAAiC;CAC9D,MAAM,WAAW,OAAO,aAAa;CAMrC,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
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The shape of a Metro / Expo config `withAui` accepts. Typed loosely so this
|
|
4
|
+
* package needs no hard dependency on `metro` or `expo`; the input shape is
|
|
5
|
+
* preserved and only `transformer.babelTransformerPath` is augmented.
|
|
6
|
+
*/
|
|
7
|
+
type MetroConfigLike = {
|
|
8
|
+
transformer?: {
|
|
9
|
+
babelTransformerPath?: string | undefined;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
} | undefined;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Env var the transformer reads to delegate to the project's existing
|
|
16
|
+
* (Expo / React Native) babel transformer. Metro forks its transform workers
|
|
17
|
+
* after `metro.config` is evaluated, so they inherit this value.
|
|
18
|
+
*/
|
|
19
|
+
declare const UPSTREAM_TRANSFORMER_ENV = "AUI_METRO_UPSTREAM_TRANSFORMER";
|
|
20
|
+
/**
|
|
21
|
+
* Wraps a Metro (or Expo) config so assistant-ui `"use generative"` modules are
|
|
22
|
+
* compiled. Such a file colocates a tool's schema, its `execute`, and its
|
|
23
|
+
* `render` via {@link https://www.assistant-ui.com/docs/tools/defining-tools | defineToolkit}.
|
|
24
|
+
*
|
|
25
|
+
* It points Metro's `babelTransformerPath` at this package's transformer, which
|
|
26
|
+
* runs the `"use generative"` compiler and then delegates to your project's
|
|
27
|
+
* existing transformer. The device (client) build keeps each tool's `render`
|
|
28
|
+
* and any frontend `execute`; a server build (an Expo Router `+api` route)
|
|
29
|
+
* keeps a server `execute` instead.
|
|
30
|
+
*
|
|
31
|
+
* ```js
|
|
32
|
+
* // metro.config.js
|
|
33
|
+
* const { getDefaultConfig } = require("expo/metro-config");
|
|
34
|
+
* const { withAui } = require("@assistant-ui/metro");
|
|
35
|
+
*
|
|
36
|
+
* module.exports = withAui(getDefaultConfig(__dirname));
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* Authoring is identical to the web: a `"use generative"` file whose default
|
|
40
|
+
* export is `defineToolkit({ ... })`, registered with `Tools({ toolkit })`.
|
|
41
|
+
*/
|
|
42
|
+
declare function withAui<T extends MetroConfigLike>(config: T): T;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { MetroConfigLike, UPSTREAM_TRANSFORMER_ENV, withAui };
|
|
45
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;AASA;;;;KAAY,eAAA;EACV,WAAA;IAEM,oBAAA;IAAA,CACC,GAAA;EAAA;EAAA,CAGN,GAAA;AAAA;;;;AAQkC;AAwBrC;cAxBa,wBAAA;;;;;;;;;;;;;AAwBmD;;;;;;;;;;iBAAhD,OAAA,WAAkB,eAAA,EAAiB,MAAA,EAAQ,CAAA,GAAI,CAAA"}
|