@aihu/magna 0.2.5

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/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # @aihu/magna
2
+
3
+ > **Aihu** — agentic discovery and interaction, for human purpose.
4
+
5
+ aihu bridge for Magna GraphQL — dep-free fetch, resource composition, JWT relay
6
+
7
+ Held-private workspace package. Not yet published to npm.
8
+
9
+ > **Status:** Held private — not yet published to npm. See [v1.1 roadmap](../../docs/roadmap/SUMMARY.md) for ratification gating (e.g. RFC #56 live-binding for `@aihu/plugin` enforcement).
10
+
11
+ <!-- BEGIN_HANDWRITTEN: prose -->
12
+ # optional, build-time only — graceful-skips if absent
13
+ bun add @aihu/magna-gqlmin
14
+ ```
15
+
16
+ Full documentation: see `apps/docs/src/content/docs/packages/magna.md` (filed as A1 issue).
17
+ <!-- END_HANDWRITTEN: prose -->
18
+
19
+ ## Install
20
+
21
+ <!-- BEGIN_AUTOGEN: install -->
22
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
23
+
24
+ ```bash
25
+ npm install @aihu/magna
26
+ # or
27
+ bun add @aihu/magna
28
+ ```
29
+
30
+ <sub><i>Auto-generated against `@aihu/magna@0.2.5`.</i></sub>
31
+
32
+ <!-- END_AUTOGEN: install -->
33
+
34
+ ## Package facts
35
+
36
+ <!-- BEGIN_AUTOGEN: stats -->
37
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
38
+
39
+ | | |
40
+ |---|---|
41
+ | **Version** | `0.2.5` |
42
+ | **Tier** | B — Meta-framework — dep-free Magna GraphQL bridge (resources + JWT relay) |
43
+ | **Bundle size** | 758 B (gz) — limit 1.8 KB |
44
+ | **Published files** | 2 entries |
45
+ | **License** | MIT |
46
+
47
+ <sub><i>Auto-generated against `@aihu/magna@0.2.5`.</i></sub>
48
+
49
+ <!-- END_AUTOGEN: stats -->
50
+
51
+ ## Exports
52
+
53
+ <!-- BEGIN_AUTOGEN: exports -->
54
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
55
+
56
+ | Subpath | ESM | CJS |
57
+ |---|---|---|
58
+ | `.` | `./dist/index.js` | `—` |
59
+ | `./codegen` | `./dist/codegen.js` | `—` |
60
+
61
+ <sub><i>Auto-generated against `@aihu/magna@0.2.5`.</i></sub>
62
+
63
+ <!-- END_AUTOGEN: exports -->
64
+
65
+ ## Dependencies
66
+
67
+ <!-- BEGIN_AUTOGEN: deps -->
68
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
69
+
70
+ **Dependencies:**
71
+
72
+ - `@aihu/signals` — `workspace:*`
73
+ - `@aihu/plugin` — `workspace:*`
74
+ - `@aihu/context` — `workspace:*`
75
+ - `@aihu-plugin/data` — `workspace:*`
76
+
77
+ **Optional dependencies (platform-specific):**
78
+
79
+ - `@aihu/magna-gqlmin` — `^0.2.0`
80
+
81
+ <sub><i>Auto-generated against `@aihu/magna@0.2.5`.</i></sub>
82
+
83
+ <!-- END_AUTOGEN: deps -->
84
+
85
+ ## See also
86
+
87
+ <!-- BEGIN_AUTOGEN: see-also -->
88
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
89
+
90
+ - [@aihu-plugin/data](../plugin-data)
91
+ - [@aihu/server](../server)
92
+ - [Aihu framework root](../../README.md)
93
+
94
+ <sub><i>Auto-generated against `@aihu/magna@0.2.5`.</i></sub>
95
+
96
+ <!-- END_AUTOGEN: see-also -->
97
+
98
+ ## License
99
+
100
+ <!-- BEGIN_AUTOGEN: license -->
101
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
102
+
103
+ MIT — see [LICENSE](../../LICENSE).
104
+
105
+ <sub><i>Auto-generated against `@aihu/magna@0.2.5`.</i></sub>
106
+
107
+ <!-- END_AUTOGEN: license -->
@@ -0,0 +1,42 @@
1
+ import { i as MagnaPluginOptions, t as MagnaBuildContext } from "./types-BNK5lubM.js";
2
+ import { Plugin } from "@aihu/plugin";
3
+
4
+ //#region src/codegen.d.ts
5
+ /**
6
+ * Run the beforeCompile SDL pipeline.
7
+ *
8
+ * All failures are handled gracefully — the build is never aborted; instead
9
+ * a warning is recorded and `magna.untyped` is set to `true` so consumers
10
+ * know typed generation was skipped.
11
+ */
12
+ declare function beforeCompile(ctx: MagnaBuildContext): Promise<void>;
13
+ //#endregion
14
+ //#region src/plugin.d.ts
15
+ /**
16
+ * Create the @aihu/magna plugin.
17
+ *
18
+ * Wires the SDL validation pipeline into the `beforeCompile` hook so that
19
+ * typed GraphQL bindings are generated (or gracefully skipped) at build time.
20
+ */
21
+ declare function magna(options: MagnaPluginOptions): Plugin;
22
+ //#endregion
23
+ //#region src/warnings.d.ts
24
+ /**
25
+ * Append `message` to `<outputDir>/.aihu/magna-warnings.json` unless it is
26
+ * already present (coalesce duplicate warnings across multiple build runs or
27
+ * hook invocations within the same run).
28
+ *
29
+ * File format: `{ "messages": ["..."] }`
30
+ */
31
+ declare function writeWarnOnce(outputDir: string, message: string): void;
32
+ /**
33
+ * Deep-merge `value` into `<outputDir>/.aihu/build-flags.json` at the given
34
+ * dot-notation `key` (e.g. `'magna.untyped'` → `{ magna: { untyped: value } }`).
35
+ *
36
+ * Existing sibling keys at each nesting level are preserved; only the target
37
+ * leaf is overwritten.
38
+ */
39
+ declare function setBuildFlag(outputDir: string, key: string, value: unknown): void;
40
+ //#endregion
41
+ export { beforeCompile, magna, setBuildFlag, writeWarnOnce };
42
+ //# sourceMappingURL=codegen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.d.ts","names":[],"sources":["../src/codegen.ts","../src/plugin.ts","../src/warnings.ts"],"mappings":";;;;;;;AAgCA;;;;iBAAsB,aAAA,CAAc,GAAA,EAAK,iBAAA,GAAoB,OAAO;;;;;;;;ACHV;iBAA1C,KAAA,CAAM,OAAA,EAAS,kBAAA,GAAqB,MAAM;;;;;;;ADG1D;;;iBEQgB,aAAA,CAAc,SAAA,UAAmB,OAAe;;;;;AFRI;;;iBE4BpD,YAAA,CAAa,SAAA,UAAmB,GAAA,UAAa,KAAA"}
@@ -0,0 +1,3 @@
1
+ import{existsSync as e,mkdirSync as t,readFileSync as n,writeFileSync as r}from"node:fs";import{dirname as i,isAbsolute as a,join as o}from"node:path";import{definePlugin as s}from"@aihu/plugin";function c(e){return o(e,`.aihu`)}function l(n){e(n)||t(n,{recursive:!0})}function u(t,r){if(!e(t))return r;try{return JSON.parse(n(t,`utf8`))}catch{return r}}function d(e,t){let n=c(e);l(n);let i=o(n,`magna-warnings.json`),a=u(i,{messages:[]});a.messages.includes(t)||(a.messages.push(t),r(i,JSON.stringify(a,null,2),`utf8`))}function f(e,t,n){let a=c(e);l(a);let s=u(o(a,`build-flags.json`),{}),d=t.split(`.`),f=s;for(let e=0;e<d.length-1;e++){let t=d[e];(typeof f[t]!=`object`||f[t]===null||Array.isArray(f[t]))&&(f[t]={}),f=f[t]}let p=d[d.length-1];f[p]=n;let m=o(c(e),`build-flags.json`);l(i(m)),r(m,JSON.stringify(s,null,2),`utf8`)}async function p(s){let{outputDir:c,projectRoot:l}=s,{options:u,outputPath:p}=s.magna,m=u.schemaPath??`schema.graphql`,h=a(m)?m:o(l,m),g;try{g=await import(`@aihu/magna-gqlmin`)}catch{d(c,`gqlmin not installed; SDL validation skipped. createMagnaResource will use untyped string-template GraphQL.`),f(c,`magna.untyped`,!0);return}if(!e(h)){d(c,`schema not found at ${h}; resources will be untyped.`),f(c,`magna.untyped`,!0);return}let _=n(h,`utf8`);try{g.parseSchema(_)}catch(e){d(c,`SDL parse error in ${h}: ${e.message??String(e)}; resources will be untyped.`),f(c,`magna.untyped`,!0);return}let v=a(p)?p:o(l,p);t(i(v),{recursive:!0}),r(v,[`// AUTO-GENERATED by @aihu/magna beforeCompile. Do not edit.`,`// Schema: ${h}`,`// Generated: ${new Date().toISOString()}`,``,`// Typed bindings will be populated when @aihu/magna-gqlmin codegen is implemented.`,`export {}`,``].join(`
2
+ `),`utf8`),f(c,`magna.untyped`,!1)}function m(e){return s({name:`@aihu/magna`,version:`0.1.0`,namespace:`magna`,aihuVersion:`^0.2.0`,hooks:{beforeCompile:async t=>{await p({...t,magna:{options:e,untyped:!1,outputPath:`src/generated/magna.ts`,warnings:[]}})}}})}export{p as beforeCompile,m as magna,f as setBuildFlag,d as writeWarnOnce};
3
+ //# sourceMappingURL=codegen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.js","names":[],"sources":["../src/warnings.ts","../src/codegen.ts","../src/plugin.ts"],"sourcesContent":["/**\n * @aihu/magna — build-time warning and flag helpers.\n *\n * This module is build-time ONLY. It uses Node.js `node:fs` to read and write\n * JSON files in the output directory. It MUST NOT be imported in browser bundles.\n *\n * Two helpers:\n * writeWarnOnce — coalescing warn logger (deduplicates messages)\n * setBuildFlag — deep-merge key/value into build-flags.json\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\n\n/** Absolute path to the .aihu/ directory inside outputDir. */\nfunction aihuDir(outputDir: string): string {\n return join(outputDir, '.aihu')\n}\n\nfunction ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\nfunction readJson<T>(filePath: string, fallback: T): T {\n if (!existsSync(filePath)) return fallback\n try {\n return JSON.parse(readFileSync(filePath, 'utf8')) as T\n } catch {\n return fallback\n }\n}\n\n/**\n * Append `message` to `<outputDir>/.aihu/magna-warnings.json` unless it is\n * already present (coalesce duplicate warnings across multiple build runs or\n * hook invocations within the same run).\n *\n * File format: `{ \"messages\": [\"...\"] }`\n */\nexport function writeWarnOnce(outputDir: string, message: string): void {\n const dir = aihuDir(outputDir)\n ensureDir(dir)\n\n const filePath = join(dir, 'magna-warnings.json')\n const data = readJson<{ messages: string[] }>(filePath, { messages: [] })\n\n if (!data.messages.includes(message)) {\n data.messages.push(message)\n writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8')\n }\n}\n\n/**\n * Deep-merge `value` into `<outputDir>/.aihu/build-flags.json` at the given\n * dot-notation `key` (e.g. `'magna.untyped'` → `{ magna: { untyped: value } }`).\n *\n * Existing sibling keys at each nesting level are preserved; only the target\n * leaf is overwritten.\n */\nexport function setBuildFlag(outputDir: string, key: string, value: unknown): void {\n const dir = aihuDir(outputDir)\n ensureDir(dir)\n\n const filePath = join(dir, 'build-flags.json')\n const root = readJson<Record<string, unknown>>(filePath, {})\n\n // Walk dot-notation segments and deep-merge.\n const segments = key.split('.')\n let cursor: Record<string, unknown> = root\n\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i] as string\n if (typeof cursor[seg] !== 'object' || cursor[seg] === null || Array.isArray(cursor[seg])) {\n cursor[seg] = {}\n }\n cursor = cursor[seg] as Record<string, unknown>\n }\n\n const leaf = segments[segments.length - 1] as string\n cursor[leaf] = value\n\n const absPath = join(aihuDir(outputDir), 'build-flags.json')\n ensureDir(dirname(absPath))\n writeFileSync(absPath, JSON.stringify(root, null, 2), 'utf8')\n}\n","/**\n * @aihu/magna — beforeCompile SDL pipeline.\n *\n * Implements the SDL validation + typed-binding generation step that runs during\n * the aihu build phase. Gracefully skips when @aihu/magna-gqlmin is absent.\n *\n * Pipeline (per brief):\n * 1. Resolve schemaPath (default 'schema.graphql') against ctx.projectRoot.\n * 2. Try to import @aihu/magna-gqlmin. On failure → warn + untyped=true, return.\n * 3. Check if schema file exists. If not → warn + untyped=true, return.\n * 4. Parse SDL via gqlmin.parseSchema(). On parse error → warn + untyped=true, return.\n * 5. Emit typed bindings to outputPath (default 'src/generated/magna.ts').\n * 6. setBuildFlag(magna.untyped, false).\n *\n * This module is build-time ONLY (uses node:fs). Never imported in browser bundles.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, isAbsolute, join } from 'node:path'\nimport type { MagnaBuildContext } from './types.js'\nimport { setBuildFlag, writeWarnOnce } from './warnings.js'\n\ninterface GqlminModule {\n parseSchema: (sdl: string) => unknown\n}\n\n/**\n * Run the beforeCompile SDL pipeline.\n *\n * All failures are handled gracefully — the build is never aborted; instead\n * a warning is recorded and `magna.untyped` is set to `true` so consumers\n * know typed generation was skipped.\n */\nexport async function beforeCompile(ctx: MagnaBuildContext): Promise<void> {\n const { outputDir, projectRoot } = ctx\n const { options, outputPath } = ctx.magna\n\n // 1. Resolve schemaPath\n const rawPath = options.schemaPath ?? 'schema.graphql'\n const schemaAbsPath = isAbsolute(rawPath) ? rawPath : join(projectRoot, rawPath)\n\n // 2. Try to import @aihu/magna-gqlmin\n let gqlmin: GqlminModule\n try {\n // @ts-expect-error — @aihu/magna-gqlmin is optional; graceful-skip when absent\n // eslint-disable-next-line\n gqlmin = (await import(/* @vite-ignore */ '@aihu/magna-gqlmin')) as GqlminModule\n } catch {\n writeWarnOnce(\n outputDir,\n 'gqlmin not installed; SDL validation skipped. createMagnaResource will use untyped string-template GraphQL.',\n )\n setBuildFlag(outputDir, 'magna.untyped', true)\n return\n }\n\n // 3. Check if schema file exists\n if (!existsSync(schemaAbsPath)) {\n writeWarnOnce(outputDir, `schema not found at ${schemaAbsPath}; resources will be untyped.`)\n setBuildFlag(outputDir, 'magna.untyped', true)\n return\n }\n\n // 4. Parse the SDL\n const sdl = readFileSync(schemaAbsPath, 'utf8')\n let _ast: unknown\n try {\n _ast = gqlmin.parseSchema(sdl)\n } catch (err) {\n writeWarnOnce(\n outputDir,\n `SDL parse error in ${schemaAbsPath}: ${(err as Error).message ?? String(err)}; resources will be untyped.`,\n )\n setBuildFlag(outputDir, 'magna.untyped', true)\n return\n }\n\n // 5. Emit typed bindings\n const absOutputPath = isAbsolute(outputPath) ? outputPath : join(projectRoot, outputPath)\n mkdirSync(dirname(absOutputPath), { recursive: true })\n writeFileSync(\n absOutputPath,\n [\n '// AUTO-GENERATED by @aihu/magna beforeCompile. Do not edit.',\n `// Schema: ${schemaAbsPath}`,\n `// Generated: ${new Date().toISOString()}`,\n '',\n '// Typed bindings will be populated when @aihu/magna-gqlmin codegen is implemented.',\n 'export {}',\n '',\n ].join('\\n'),\n 'utf8',\n )\n\n // 6. Mark as typed\n setBuildFlag(outputDir, 'magna.untyped', false)\n}\n","/**\n * @aihu/magna — plugin factory.\n *\n * `magna(options)` returns a `Plugin` that wires the SDL pipeline into the\n * aihu `beforeCompile` build hook. Register it in `defineAihuConfig`:\n *\n * @example\n * // aihu.config.ts\n * import { magna } from '@aihu/magna'\n * import { defineAihuConfig } from '@aihu/server'\n *\n * export default defineAihuConfig({\n * plugins: [\n * magna({ url: process.env.MAGNA_GRAPHQL_URL! }),\n * ],\n * })\n */\n\nimport type { Plugin } from '@aihu/plugin'\nimport { definePlugin } from '@aihu/plugin'\nimport { beforeCompile } from './codegen.js'\nimport type { MagnaBuildContext, MagnaPluginOptions } from './types.js'\n\n/**\n * Create the @aihu/magna plugin.\n *\n * Wires the SDL validation pipeline into the `beforeCompile` hook so that\n * typed GraphQL bindings are generated (or gracefully skipped) at build time.\n */\nexport function magna(options: MagnaPluginOptions): Plugin {\n return definePlugin({\n name: '@aihu/magna',\n version: '0.1.0',\n namespace: 'magna',\n aihuVersion: '^0.2.0',\n hooks: {\n beforeCompile: async (ctx) => {\n const magnaCtx: MagnaBuildContext = {\n ...ctx,\n magna: {\n options,\n untyped: false,\n outputPath: 'src/generated/magna.ts',\n warnings: [],\n },\n }\n await beforeCompile(magnaCtx)\n },\n },\n })\n}\n"],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import { a as MagnaResource, i as MagnaPluginOptions, n as MagnaFetch, o as MagnaSubscriptionHandle, r as MagnaJwtRelay, t as MagnaBuildContext } from "./types-BNK5lubM.js";
2
+ import { Signal } from "@aihu/signals";
3
+ import { ResourceOptions } from "@aihu-plugin/data";
4
+
5
+ //#region ../context/src/index.d.ts
6
+ /**
7
+ * @aihu/context — zero-dependency, DOM-free context system.
8
+ *
9
+ * Provides a React-style context API suitable for both SSR (via
10
+ * setSsrContextMap / clearSsrContextMap / runWithContext) and client-side
11
+ * usage. No external imports; no DOM references.
12
+ */
13
+ /**
14
+ * Opaque token that identifies a context slot and carries its default value.
15
+ */
16
+ interface ContextToken<T> {
17
+ readonly _id: symbol;
18
+ readonly _default: T | undefined;
19
+ }
20
+ //#endregion
21
+ //#region src/context.d.ts
22
+ declare const MagnaFetchToken: ContextToken<MagnaFetch>;
23
+ //#endregion
24
+ //#region src/fetch.d.ts
25
+ /**
26
+ * Create a typed GraphQL fetch function bound to the given options.
27
+ *
28
+ * JWT relay: reads `options.getToken?.()` per request. When the getter
29
+ * returns a non-null string the Authorization header is added; when it
30
+ * returns null the header is omitted entirely (per relay spec).
31
+ *
32
+ * Static headers in `options.headers` are merged before the per-call
33
+ * Authorization header so callers can override if needed.
34
+ *
35
+ * Network failures propagate as thrown errors. GraphQL-level errors are
36
+ * returned inside the response envelope (`{ data: null, errors: [...] }`).
37
+ */
38
+ declare function createMagnaFetch(options: MagnaPluginOptions): MagnaFetch;
39
+ //#endregion
40
+ //#region src/resource.d.ts
41
+ /**
42
+ * Create a reactive Magna GraphQL resource.
43
+ *
44
+ * @param fetch Magna fetch function (from createMagnaFetch).
45
+ * @param operation GraphQL operation string (query/mutation).
46
+ * @param variables Optional reactive signal whose value is passed as variables.
47
+ * When the signal value changes the resource automatically
48
+ * re-fetches with the new variables. A null signal value puts
49
+ * the resource into idle state (no fetch).
50
+ * @param options Optional ResourceOptions forwarded to createResource
51
+ * (initialData, dehydrate, store).
52
+ *
53
+ * Returns a Resource<T> (state, refetch, invalidate).
54
+ */
55
+ declare function createMagnaResource<T>(fetch: MagnaFetch, operation: string, variables?: Signal<Readonly<Record<string, unknown>> | null>, options?: ResourceOptions<T>): MagnaResource<T>;
56
+ //#endregion
57
+ //#region src/subscription.d.ts
58
+ /**
59
+ * Return a degraded subscription handle.
60
+ *
61
+ * The handle contains:
62
+ * - `state`: a signal always holding null (no streaming data yet).
63
+ * - `close`: idempotent no-op.
64
+ * - `degraded`: always true in v0.1.
65
+ *
66
+ * A warn-once message is emitted via console.warn on first call.
67
+ */
68
+ declare function useMagnaSubscription<T>(): MagnaSubscriptionHandle<T>;
69
+ //#endregion
70
+ export { type MagnaBuildContext, type MagnaFetch, MagnaFetchToken, type MagnaJwtRelay, type MagnaPluginOptions, type MagnaResource, type MagnaSubscriptionHandle, createMagnaFetch, createMagnaResource, useMagnaSubscription };
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../context/src/index.ts","../src/context.ts","../src/fetch.ts","../src/resource.ts","../src/subscription.ts"],"mappings":";;;;;;;;;;AAWA;;;;;UAAiB,YAAA;EAAA,SACN,GAAA;EAAA,SACA,QAAA,EAAU,CAAC;AAAA;;;cCMT,eAAA,EAAe,YAAA,CAAA,UAAA;;;;;;;;;;ADNN;;;;ACMtB;;iBCEgB,gBAAA,CAAiB,OAAA,EAAS,kBAAA,GAAqB,UAAU;;;;;ADFzE;;;;AAA4B;;;;ACE5B;;;;iBCsCgB,mBAAA,GAAA,CACd,KAAA,EAAO,UAAA,EACP,SAAA,UACA,SAAA,GAAY,MAAA,CAAO,QAAA,CAAS,MAAA,4BAC5B,OAAA,GAAU,eAAA,CAAgB,CAAA,IACzB,aAAA,CAAc,CAAA;;;;;;;AHnDK;;;;ACMtB;;iBGOgB,oBAAA,GAAA,CAAA,GAA2B,uBAAuB,CAAC,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import{signal as e}from"@aihu/signals";import{createResource as t}from"@aihu-plugin/data";function n(e){return{_id:Symbol(`aihu.context`),_default:e}}const r=n();function i(e){let t=e.fetch??globalThis.fetch;return async function(n,r){let i={"content-type":`application/json`,...e.headers},a=e.getToken?.()??null;a!==null&&(i.authorization=`Bearer ${a}`);let o=JSON.stringify({query:n,...r===void 0?{}:{variables:r}}),s=await(await t(e.url,{method:`POST`,headers:i,body:o})).json();return{data:s.data??null,...s.errors?{errors:s.errors}:{}}}}function a(e){if(e==null)return`{}`;let t={};for(let n of Object.keys(e).sort())t[n]=e[n];return JSON.stringify(t)}function o(e,t){return`${e}|${a(t)}`}function s(n,r,i,a){let[s,c]=e(i?o(r,i[0]()):o(r,void 0)),l=i?[()=>{let e=i[0]();return e===null?null:o(r,e)},c]:[()=>s(),c];async function u(e){let t=await n(r,i?i[0]()??void 0:void 0);if(t.errors&&t.errors.length>0){let e=t.errors.map(e=>e.message).join(`; `);throw Error(`GraphQL error: ${e}`)}return t.data}return t(l,u,a)}let c=!1;function l(){c||(c=!0,console.warn(`magna subscriptions require v0.2 streaming; returning degraded handle`));let[t]=e(null);return{state:[t,()=>{}],close(){},degraded:!0}}export{r as MagnaFetchToken,i as createMagnaFetch,s as createMagnaResource,l as useMagnaSubscription};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../context/src/index.ts","../src/context.ts","../src/fetch.ts","../src/resource.ts","../src/subscription.ts"],"sourcesContent":["/**\n * @aihu/context — zero-dependency, DOM-free context system.\n *\n * Provides a React-style context API suitable for both SSR (via\n * setSsrContextMap / clearSsrContextMap / runWithContext) and client-side\n * usage. No external imports; no DOM references.\n */\n\n/**\n * Opaque token that identifies a context slot and carries its default value.\n */\nexport interface ContextToken<T> {\n readonly _id: symbol\n readonly _default: T | undefined\n}\n\n/**\n * Module-level active context map. Set by setSsrContextMap or runWithContext;\n * cleared by clearSsrContextMap. null means no map is active.\n *\n * This is the FLAT, SSR-oriented path — one map per request, no tree scoping.\n * Left unchanged so existing SSR consumers keep working.\n */\nlet _activeContextMap: Map<symbol, unknown> | null = null\n\n/**\n * Client hierarchical path. During a component's setup the runtime installs that\n * component's `provides` object here — a plain object whose prototype chain IS\n * the ancestor context tree (each subtree that provides does `Object.create` of\n * its parent's object). `inject` becomes a single prototype-chain lookup, and an\n * ancestor's provide is visible to descendants but not to siblings.\n *\n * `_ownProvides` tracks whether the active object is THIS owner's own (already\n * `Object.create`d) or still a shared reference to the parent's — so the first\n * `provide()` allocates exactly once and hands the new object back to the runtime\n * to store on the instance for descendants to inherit.\n *\n * Null when not inside a client component setup (then the SSR map, or the token\n * default, applies) — so nothing changes for SSR or standalone use.\n */\nlet _activeProvides: Record<symbol, unknown> | null = null\nlet _ownProvides = false\nlet _onOwnProvides: ((own: Record<symbol, unknown>) => void) | null = null\n\n/**\n * Create a new context token. Optionally provide a default value that\n * inject() returns when no value has been provided for this token.\n */\nexport function createContext<T>(defaultValue?: T): ContextToken<T> {\n return {\n _id: Symbol('aihu.context'),\n _default: defaultValue,\n }\n}\n\n/**\n * Interned string-key → token map for `contextKey`. Module-global on purpose:\n * every component in the app must agree on the token for a given key.\n */\nconst _stringTokens = new Map<string, ContextToken<unknown>>()\n\n/**\n * Intern a stable context token for a string key, so the compiler-lowered\n * `$context` provide/consume (which are string-keyed) resolve to one shared\n * token app-wide. Module-global, so every component agrees on the token for a\n * key.\n */\nexport function contextKey(key: string): ContextToken<unknown> {\n let t = _stringTokens.get(key)\n if (t === undefined) {\n t = createContext<unknown>()\n _stringTokens.set(key, t)\n }\n return t\n}\n\n/**\n * Write a value for the given token into the active context map.\n * If no map is currently active, this is a no-op.\n */\nexport function provide<T>(token: ContextToken<T>, value: T): void {\n // Client hierarchical path takes precedence when a component setup is active.\n if (_activeProvides !== null || _onOwnProvides !== null) {\n if (!_ownProvides) {\n // First provide by this owner: allocate its own object inheriting the\n // parent's, and hand it back so the runtime stores it on the instance for\n // descendants to inherit. `?? null` roots the chain when there is no parent.\n _activeProvides = Object.create(_activeProvides ?? null) as Record<symbol, unknown>\n _ownProvides = true\n _onOwnProvides?.(_activeProvides)\n }\n _activeProvides![token._id] = value\n return\n }\n if (_activeContextMap === null) return\n _activeContextMap.set(token._id, value)\n}\n\n/**\n * Read a value for the given token. On the client hierarchical path this is a\n * single prototype-chain lookup (an ancestor's provide is visible here). Falls\n * back to the flat SSR map, then the token default.\n */\nexport function inject<T>(token: ContextToken<T>): T | undefined {\n if (_activeProvides !== null) {\n return (token._id in _activeProvides ? _activeProvides[token._id] : token._default) as\n | T\n | undefined\n }\n if (_activeContextMap === null) return token._default\n if (_activeContextMap.has(token._id)) {\n return _activeContextMap.get(token._id) as T\n }\n return token._default\n}\n\n/**\n * @internal — runtime hook. Enter a component's context scope for the duration of\n * its setup: `parent` is the resolved ancestor `provides` object (or null at the\n * root), and `onOwn` is called with this owner's own object the first time it\n * `provide`s, so the runtime can store it on the instance for descendants.\n * Returns the previous scope for `_exitContext` to restore (setups nest).\n */\nexport function _enterContext(\n parent: Record<symbol, unknown> | null,\n onOwn: (own: Record<symbol, unknown>) => void,\n): [Record<symbol, unknown> | null, boolean, ((own: Record<symbol, unknown>) => void) | null] {\n const prev: [\n Record<symbol, unknown> | null,\n boolean,\n ((own: Record<symbol, unknown>) => void) | null,\n ] = [_activeProvides, _ownProvides, _onOwnProvides]\n _activeProvides = parent\n _ownProvides = false\n _onOwnProvides = onOwn\n return prev\n}\n\n/** @internal — restore the scope captured by `_enterContext`. */\nexport function _exitContext(\n prev: [Record<symbol, unknown> | null, boolean, ((own: Record<symbol, unknown>) => void) | null],\n): void {\n _activeProvides = prev[0]\n _ownProvides = prev[1]\n _onOwnProvides = prev[2]\n}\n\n/**\n * Set the active context map (SSR entry point).\n * Replaces any previously active map.\n */\nexport function setSsrContextMap(map: Map<symbol, unknown>): void {\n _activeContextMap = map\n}\n\n/**\n * Clear the active context map (SSR teardown).\n */\nexport function clearSsrContextMap(): void {\n _activeContextMap = null\n}\n\n/**\n * Run fn() with the given map as the active context map, then restore\n * the previous state (null) in a finally block.\n *\n * This is the recommended SSR entry point: each request gets its own\n * Map; context leakage between requests is impossible.\n */\nexport function runWithContext<R>(map: Map<symbol, unknown>, fn: () => R): R {\n setSsrContextMap(map)\n try {\n return fn()\n } finally {\n clearSsrContextMap()\n }\n}\n","/**\n * @aihu/magna — injection token for the Magna fetch function.\n *\n * The compiler lowers `$query name = data.X.query(vars)` (and magna-origin\n * `$resource` entries) to\n * `const name = createMagnaResource(inject(MagnaFetchToken), data.X.query(vars))`.\n * `MagnaFetchToken` is the context token that `inject(...)` resolves at\n * component setup so `createMagnaResource` receives its `MagnaFetch`.\n *\n * Provide at app root: `provide(MagnaFetchToken, createMagnaFetch(options))`.\n * Inject in setup: `const fetch = inject(MagnaFetchToken)`.\n *\n * Mirrors the @aihu-plugin/data `ResourceStoreToken` pattern\n * (packages/plugin-data/src/store.ts). No default value — `inject` returns\n * `undefined` when no fetch is provided.\n */\nimport { createContext } from '@aihu/context'\nimport type { MagnaFetch } from './types.js'\n\nexport const MagnaFetchToken = createContext<MagnaFetch>()\n","/**\n * @aihu/magna — dep-free GraphQL fetch with JWT relay.\n *\n * createMagnaFetch builds a typed GraphQL POST wrapper. No external deps;\n * uses globalThis.fetch (or options.fetch for testing/edge environments).\n */\nimport type { MagnaFetch, MagnaPluginOptions } from './types.js'\n\n/**\n * Create a typed GraphQL fetch function bound to the given options.\n *\n * JWT relay: reads `options.getToken?.()` per request. When the getter\n * returns a non-null string the Authorization header is added; when it\n * returns null the header is omitted entirely (per relay spec).\n *\n * Static headers in `options.headers` are merged before the per-call\n * Authorization header so callers can override if needed.\n *\n * Network failures propagate as thrown errors. GraphQL-level errors are\n * returned inside the response envelope (`{ data: null, errors: [...] }`).\n */\nexport function createMagnaFetch(options: MagnaPluginOptions): MagnaFetch {\n const fetchImpl = options.fetch ?? globalThis.fetch\n\n return async function magnaFetch<TData = unknown>(\n operation: string,\n variables?: Readonly<Record<string, unknown>>,\n ): Promise<{\n readonly data: TData | null\n readonly errors?: ReadonlyArray<{ readonly message: string }>\n }> {\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n ...options.headers,\n }\n\n const token = options.getToken?.() ?? null\n if (token !== null) {\n headers.authorization = `Bearer ${token}`\n }\n\n const body = JSON.stringify({\n query: operation,\n ...(variables !== undefined ? { variables } : {}),\n })\n\n const response = await fetchImpl(options.url, {\n method: 'POST',\n headers,\n body,\n })\n\n const json = (await response.json()) as {\n data?: TData | null\n errors?: Array<{ message: string }>\n }\n\n return {\n data: json.data ?? null,\n ...(json.errors ? { errors: json.errors } : {}),\n }\n }\n}\n","/**\n * @aihu/magna — resource composition over @aihu-plugin/data.\n *\n * createMagnaResource wraps createResource with a cache-key strategy that\n * combines the GraphQL operation string + serialised variables. The key signal\n * is derived from an optional reactive variables signal so queries automatically\n * re-fetch when variables change.\n *\n * Cache-key strategy (Builder-time decision): alphabetically-sorted key\n * serialisation via JSON.stringify — dep-free, ~15 LOC, deterministic.\n * Variables `{ b: 2, a: 1 }` and `{ a: 1, b: 2 }` produce the same key,\n * preventing spurious cache misses from object-property-ordering differences.\n */\n\nimport type { Signal } from '@aihu/signals'\nimport { signal } from '@aihu/signals'\nimport type { ResourceOptions } from '@aihu-plugin/data'\nimport { createResource } from '@aihu-plugin/data'\nimport type { MagnaFetch, MagnaResource } from './types.js'\n\n/**\n * Alphabetically-sorted JSON serialisation of an object.\n * Produces a stable string regardless of property insertion order.\n * Returns '{}' for null/undefined input (maps to \"no variables\").\n */\nfunction stableSerialise(obj: Readonly<Record<string, unknown>> | null | undefined): string {\n if (obj == null) return '{}'\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(obj).sort()) {\n sorted[k] = obj[k]\n }\n return JSON.stringify(sorted)\n}\n\n/**\n * Build a stable cache key from the operation string and current variables.\n * Format: `<operation>|<sorted-vars-json>` — unique per query+variable pair.\n */\nfunction buildCacheKey(\n operation: string,\n vars: Readonly<Record<string, unknown>> | null | undefined,\n): string {\n return `${operation}|${stableSerialise(vars)}`\n}\n\n/**\n * Create a reactive Magna GraphQL resource.\n *\n * @param fetch Magna fetch function (from createMagnaFetch).\n * @param operation GraphQL operation string (query/mutation).\n * @param variables Optional reactive signal whose value is passed as variables.\n * When the signal value changes the resource automatically\n * re-fetches with the new variables. A null signal value puts\n * the resource into idle state (no fetch).\n * @param options Optional ResourceOptions forwarded to createResource\n * (initialData, dehydrate, store).\n *\n * Returns a Resource<T> (state, refetch, invalidate).\n */\nexport function createMagnaResource<T>(\n fetch: MagnaFetch,\n operation: string,\n variables?: Signal<Readonly<Record<string, unknown>> | null>,\n options?: ResourceOptions<T>,\n): MagnaResource<T> {\n // Build a stable key signal from the operation + current variables value.\n // null variables → null key → idle state (no fetch fired).\n const [getKey, setKey] = signal<string | null>(\n variables ? buildCacheKey(operation, variables[0]()) : buildCacheKey(operation, undefined),\n )\n\n // When variables signal changes, recompute the key.\n // We wire this as an effect-like subscription via the createResource key signal.\n // The key signal passed to createResource is a derived value that reads the\n // variables signal (or a static key when variables is undefined).\n const keySignal: Signal<string | null | undefined> = variables\n ? ([\n () => {\n const vars = variables[0]()\n return vars === null ? null : buildCacheKey(operation, vars)\n },\n setKey,\n ] as unknown as Signal<string | null | undefined>)\n : ([() => getKey(), setKey] as unknown as Signal<string | null | undefined>)\n\n // Fetcher: call the magna fetch function, throw on GraphQL errors\n // (drives the resource into 'error' state).\n async function fetcher(_key: string): Promise<T> {\n // Extract variables from the key is not needed — we re-read them from the signal.\n const vars = variables ? (variables[0]() ?? undefined) : undefined\n const result = await fetch(operation, vars)\n if (result.errors && result.errors.length > 0) {\n const msgs = result.errors.map((e) => e.message).join('; ')\n throw new Error(`GraphQL error: ${msgs}`)\n }\n return result.data as T\n }\n\n return createResource<T>(keySignal, fetcher, options)\n}\n","/**\n * @aihu/magna — useMagnaSubscription v0.1 degraded shim.\n *\n * v0.2 will introduce real WebSocket/SSE streaming. Until then this shim\n * returns a handle with `degraded: true` so consumers can branch on that flag\n * without breaking when streaming lands.\n *\n * A warn-once message is emitted on first call via console.warn.\n */\n\nimport type { Signal } from '@aihu/signals'\nimport { signal } from '@aihu/signals'\nimport type { MagnaSubscriptionHandle } from './types.js'\n\nlet _warned = false\n\n/**\n * Return a degraded subscription handle.\n *\n * The handle contains:\n * - `state`: a signal always holding null (no streaming data yet).\n * - `close`: idempotent no-op.\n * - `degraded`: always true in v0.1.\n *\n * A warn-once message is emitted via console.warn on first call.\n */\nexport function useMagnaSubscription<T>(): MagnaSubscriptionHandle<T> {\n if (!_warned) {\n _warned = true\n console.warn('magna subscriptions require v0.2 streaming; returning degraded handle')\n }\n\n const [getState] = signal<T | null>(null)\n\n const noop = (): void => {\n // no-op setter — degraded handles do not accept external writes\n }\n\n return {\n state: [getState, noop] as unknown as Signal<T | null>,\n close(): void {\n // Idempotent no-op in v0.1.\n },\n degraded: true,\n }\n}\n"],"mappings":"0FAgDA,SAAgB,EAAiB,EAAmC,CAClE,MAAO,CACL,IAAK,OAAO,cAAc,EAC1B,SAAU,CACZ,CACF,CClCA,MAAa,EAAkB,EAA0B,ECEzD,SAAgB,EAAiB,EAAyC,CACxE,IAAM,EAAY,EAAQ,OAAS,WAAW,MAE9C,OAAO,eACL,EACA,EAIC,CACD,IAAM,EAAkC,CACtC,eAAgB,mBAChB,GAAG,EAAQ,OACb,EAEM,EAAQ,EAAQ,WAAW,GAAK,KAClC,IAAU,OACZ,EAAQ,cAAgB,UAAU,KAGpC,IAAM,EAAO,KAAK,UAAU,CAC1B,MAAO,EACP,GAAI,IAAc,IAAA,GAA4B,CAAC,EAAjB,CAAE,WAAU,CAC5C,CAAC,EAQK,EAAQ,MAAM,MANG,EAAU,EAAQ,IAAK,CAC5C,OAAQ,OACR,UACA,MACF,CAAC,GAE4B,KAAK,EAKlC,MAAO,CACL,KAAM,EAAK,MAAQ,KACnB,GAAI,EAAK,OAAS,CAAE,OAAQ,EAAK,MAAO,EAAI,CAAC,CAC/C,CACF,CACF,CCrCA,SAAS,EAAgB,EAAmE,CAC1F,GAAI,GAAO,KAAM,MAAO,KACxB,IAAM,EAAkC,CAAC,EACzC,IAAK,IAAM,KAAK,OAAO,KAAK,CAAG,EAAE,KAAK,EACpC,EAAO,GAAK,EAAI,GAElB,OAAO,KAAK,UAAU,CAAM,CAC9B,CAMA,SAAS,EACP,EACA,EACQ,CACR,MAAO,GAAG,EAAU,GAAG,EAAgB,CAAI,GAC7C,CAgBA,SAAgB,EACd,EACA,EACA,EACA,EACkB,CAGlB,GAAM,CAAC,EAAQ,GAAU,EACvB,EAAY,EAAc,EAAW,EAAU,GAAG,CAAC,EAAI,EAAc,EAAW,IAAA,EAAS,CAC3F,EAMM,EAA+C,EAChD,KACO,CACJ,IAAM,EAAO,EAAU,GAAG,EAC1B,OAAO,IAAS,KAAO,KAAO,EAAc,EAAW,CAAI,CAC7D,EACA,CACF,EACC,KAAO,EAAO,EAAG,CAAM,EAI5B,eAAe,EAAQ,EAA0B,CAG/C,IAAM,EAAS,MAAM,EAAM,EADd,EAAa,EAAU,GAAG,GAAK,IAAA,GAAa,IAAA,EACf,EAC1C,GAAI,EAAO,QAAU,EAAO,OAAO,OAAS,EAAG,CAC7C,IAAM,EAAO,EAAO,OAAO,IAAK,GAAM,EAAE,OAAO,EAAE,KAAK,IAAI,EAC1D,MAAU,MAAM,kBAAkB,GAAM,CAC1C,CACA,OAAO,EAAO,IAChB,CAEA,OAAO,EAAkB,EAAW,EAAS,CAAO,CACtD,CCrFA,IAAI,EAAU,GAYd,SAAgB,GAAsD,CAC/D,IACH,EAAU,GACV,QAAQ,KAAK,uEAAuE,GAGtF,GAAM,CAAC,GAAY,EAAiB,IAAI,EAMxC,MAAO,CACL,MAAO,CAAC,MALe,CAEzB,CAGwB,EACtB,OAAc,CAEd,EACA,SAAU,EACZ,CACF"}
@@ -0,0 +1,81 @@
1
+ import { Signal } from "@aihu/signals";
2
+ import { Resource } from "@aihu-plugin/data";
3
+ import { BuildContext } from "@aihu/plugin";
4
+
5
+ //#region src/types.d.ts
6
+ /** Configuration options for the magna GraphQL plugin. */
7
+ interface MagnaPluginOptions {
8
+ /** Magna GraphQL endpoint URL (e.g., https://magna.example.com/graphql). */
9
+ readonly url: string;
10
+ /** Path to the GraphQL SDL schema file. Default: 'schema.graphql'. */
11
+ readonly schemaPath?: string;
12
+ /** Static headers merged into every request. */
13
+ readonly headers?: Readonly<Record<string, string>>;
14
+ /** Git revision (informational; injected into build metadata). */
15
+ readonly gitRev?: string;
16
+ /**
17
+ * Getter for the current JWT. Called per-request.
18
+ * Return null to omit the Authorization header entirely.
19
+ */
20
+ readonly getToken?: () => string | null;
21
+ /**
22
+ * Custom fetch implementation. Defaults to globalThis.fetch.
23
+ * Useful for testing or non-standard environments.
24
+ */
25
+ readonly fetch?: typeof globalThis.fetch;
26
+ }
27
+ /**
28
+ * Typed fetch wrapper for Magna GraphQL operations.
29
+ * Sends a POST with the GraphQL envelope; returns the parsed response.
30
+ * Network failures throw; GraphQL errors are returned in the envelope.
31
+ */
32
+ type MagnaFetch = <TData = unknown>(operation: string, variables?: Readonly<Record<string, unknown>>) => Promise<{
33
+ readonly data: TData | null;
34
+ readonly errors?: ReadonlyArray<{
35
+ readonly message: string;
36
+ }>;
37
+ }>;
38
+ /** Reactive resource handle wrapping a Magna GraphQL query. */
39
+ type MagnaResource<T> = Resource<T>;
40
+ /**
41
+ * Handle returned by `useMagnaSubscription`.
42
+ * In v0.1 this is a degraded shim: subscriptions are not yet streamed.
43
+ */
44
+ interface MagnaSubscriptionHandle<T> {
45
+ /** Current value signal. Always starts as null in the v0.1 shim. */
46
+ readonly state: Signal<T | null>;
47
+ /** Idempotent close. No-op in v0.1. */
48
+ readonly close: () => void;
49
+ /**
50
+ * True when streaming is not available and the handle is a degraded fallback.
51
+ * Always true in v0.1.
52
+ */
53
+ readonly degraded: boolean;
54
+ }
55
+ /** Extended build context passed to the magna beforeCompile hook. */
56
+ interface MagnaBuildContext extends BuildContext {
57
+ readonly magna: {
58
+ readonly options: MagnaPluginOptions;
59
+ readonly untyped: boolean;
60
+ readonly outputPath: string;
61
+ readonly warnings: ReadonlyArray<string>;
62
+ };
63
+ }
64
+ /**
65
+ * JWT relay documentation artifact — describes where tokens originate in SSR
66
+ * and client contexts. This interface is never instantiated at runtime; it
67
+ * exists for IDE discoverability and schema generation.
68
+ */
69
+ interface MagnaJwtRelay {
70
+ readonly ssr: {
71
+ readonly source: 'request-context';
72
+ readonly extractor: 'requireAuth(req) → token → wrap in getToken closure';
73
+ };
74
+ readonly client: {
75
+ readonly source: 'cookie-backed-auth-signal';
76
+ readonly extractor: '@aihu/auth ScopeSignal layer reads cookie → getToken returns live value';
77
+ };
78
+ }
79
+ //#endregion
80
+ export { MagnaResource as a, MagnaPluginOptions as i, MagnaFetch as n, MagnaSubscriptionHandle as o, MagnaJwtRelay as r, MagnaBuildContext as t };
81
+ //# sourceMappingURL=types-BNK5lubM.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-BNK5lubM.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;UAYiB,kBAAA;EAkByB;EAAA,SAhB/B,GAAA;EAEA;EAAA,SAAA,UAAA;EAEU;EAAA,SAAV,OAAA,GAAU,QAAA,CAAS,MAAA;EAEnB;EAAA,SAAA,MAAA;EAUA;;;;EAAA,SALA,QAAA;EAaC;;;;EAAA,SARD,KAAA,UAAe,UAAA,CAAW,KAAA;AAAA;;;;;;KAQzB,UAAA,qBACV,SAAA,UACA,SAAA,GAAY,QAAA,CAAS,MAAA,uBAClB,OAAA;EAAA,SACM,IAAA,EAAM,KAAA;EAAA,SACN,MAAA,GAAS,aAAA;IAAA,SAAyB,OAAA;EAAA;AAAA;;KAIjC,aAAA,MAAmB,QAAQ,CAAC,CAAA;;;;AAJY;UAUnC,uBAAA;EANQ;EAAA,SAQd,KAAA,EAAO,MAAM,CAAC,CAAA;EARc;EAAA,SAU5B,KAAA;EAVoB;;;AAAU;EAAV,SAepB,QAAA;AAAA;;UAIM,iBAAA,SAA0B,YAAA;EAAA,SAChC,KAAA;IAAA,SACE,OAAA,EAAS,kBAAA;IAAA,SACT,OAAA;IAAA,SACA,UAAA;IAAA,SACA,QAAA,EAAU,aAAA;EAAA;AAAA;AATJ;AAInB;;;;AAJmB,UAkBF,aAAA;EAAA,SACN,GAAA;IAAA,SACE,MAAA;IAAA,SACA,SAAA;EAAA;EAAA,SAEF,MAAA;IAAA,SACE,MAAA;IAAA,SACA,SAAA;EAAA;AAAA"}
@@ -0,0 +1,21 @@
1
+ {
2
+ "pluginName": "@aihu/magna",
3
+ "pluginVersion": "0.2.0",
4
+ "aihuVersion": "^0.2.0",
5
+ "installSteps": [
6
+ {
7
+ "kind": "register-plugin",
8
+ "description": "Register magna plugin in aihu.config.ts"
9
+ },
10
+ {
11
+ "kind": "scaffold-env",
12
+ "description": "Add MAGNA_GRAPHQL_URL to .env.example"
13
+ }
14
+ ],
15
+ "requiredEnv": [
16
+ {
17
+ "name": "MAGNA_GRAPHQL_URL",
18
+ "description": "Magna GraphQL endpoint (e.g., https://magna.example.com/graphql)"
19
+ }
20
+ ]
21
+ }
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@aihu/magna",
3
+ "version": "0.2.5",
4
+ "description": "aihu bridge for Magna GraphQL — dep-free fetch, resource composition, JWT relay",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.js",
13
+ "types": "./dist/index.d.ts"
14
+ },
15
+ "./codegen": {
16
+ "import": "./dist/codegen.js",
17
+ "types": "./dist/codegen.d.ts"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "install-manifest.json"
23
+ ],
24
+ "sideEffects": false,
25
+ "scripts": {
26
+ "build": "rolldown -c rolldown.config.ts",
27
+ "typecheck": "tsc --noEmit",
28
+ "test": "vitest run",
29
+ "prepublishOnly": "bun run build"
30
+ },
31
+ "dependencies": {
32
+ "@aihu/signals": "0.5.0",
33
+ "@aihu/plugin": "0.1.0",
34
+ "@aihu/context": "0.2.0",
35
+ "@aihu-plugin/data": "2.0.5"
36
+ },
37
+ "optionalDependencies": {
38
+ "@aihu/magna-gqlmin": "^0.2.0"
39
+ },
40
+ "devDependencies": {
41
+ "rolldown": "^1.0.0-rc.17",
42
+ "rolldown-plugin-dts": "^0.23.2",
43
+ "typescript": "^5.6.2",
44
+ "vitest": "^3.2.6"
45
+ },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/fellwork/aihu.git",
49
+ "directory": "packages/magna"
50
+ },
51
+ "homepage": "https://github.com/fellwork/aihu/tree/main/packages/magna#readme",
52
+ "bugs": "https://github.com/fellwork/aihu/issues",
53
+ "publishConfig": {
54
+ "access": "public"
55
+ }
56
+ }