@aihu/magna 0.2.6 → 0.2.8

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 CHANGED
@@ -9,7 +9,10 @@ Held-private workspace package. Not yet published to npm.
9
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
10
 
11
11
  <!-- BEGIN_HANDWRITTEN: prose -->
12
- # optional, build-time only — graceful-skips if absent
12
+ Magna's optional build-time GraphQL parser is loaded dynamically and
13
+ gracefully skipped when absent. Install it explicitly when it becomes available:
14
+
15
+ ```bash
13
16
  bun add @aihu/magna-gqlmin
14
17
  ```
15
18
 
@@ -27,7 +30,7 @@ npm install @aihu/magna
27
30
  bun add @aihu/magna
28
31
  ```
29
32
 
30
- <sub><i>Auto-generated against `@aihu/magna@0.2.6`.</i></sub>
33
+ <sub><i>Auto-generated against `@aihu/magna@0.2.8`.</i></sub>
31
34
 
32
35
  <!-- END_AUTOGEN: install -->
33
36
 
@@ -38,13 +41,13 @@ bun add @aihu/magna
38
41
 
39
42
  | | |
40
43
  |---|---|
41
- | **Version** | `0.2.6` |
44
+ | **Version** | `0.2.8` |
42
45
  | **Tier** | B — Meta-framework — dep-free Magna GraphQL bridge (resources + JWT relay) |
43
46
  | **Bundle size** | 758 B (gz) — limit 1.8 KB |
44
47
  | **Published files** | 2 entries |
45
48
  | **License** | MIT |
46
49
 
47
- <sub><i>Auto-generated against `@aihu/magna@0.2.6`.</i></sub>
50
+ <sub><i>Auto-generated against `@aihu/magna@0.2.8`.</i></sub>
48
51
 
49
52
  <!-- END_AUTOGEN: stats -->
50
53
 
@@ -58,7 +61,7 @@ bun add @aihu/magna
58
61
  | `.` | `./dist/index.js` | `—` |
59
62
  | `./codegen` | `./dist/codegen.js` | `—` |
60
63
 
61
- <sub><i>Auto-generated against `@aihu/magna@0.2.6`.</i></sub>
64
+ <sub><i>Auto-generated against `@aihu/magna@0.2.8`.</i></sub>
62
65
 
63
66
  <!-- END_AUTOGEN: exports -->
64
67
 
@@ -69,16 +72,12 @@ bun add @aihu/magna
69
72
 
70
73
  **Dependencies:**
71
74
 
72
- - `@aihu/signals` — `workspace:*`
75
+ - `@aihu/signals` — `^0.5.1`
73
76
  - `@aihu/plugin` — `workspace:*`
74
77
  - `@aihu/context` — `workspace:*`
75
78
  - `@aihu-plugin/data` — `workspace:*`
76
79
 
77
- **Optional dependencies (platform-specific):**
78
-
79
- - `@aihu/magna-gqlmin` — `^0.2.0`
80
-
81
- <sub><i>Auto-generated against `@aihu/magna@0.2.6`.</i></sub>
80
+ <sub><i>Auto-generated against `@aihu/magna@0.2.8`.</i></sub>
82
81
 
83
82
  <!-- END_AUTOGEN: deps -->
84
83
 
@@ -91,7 +90,7 @@ bun add @aihu/magna
91
90
  - [@aihu/server](../server)
92
91
  - [Aihu framework root](../../README.md)
93
92
 
94
- <sub><i>Auto-generated against `@aihu/magna@0.2.6`.</i></sub>
93
+ <sub><i>Auto-generated against `@aihu/magna@0.2.8`.</i></sub>
95
94
 
96
95
  <!-- END_AUTOGEN: see-also -->
97
96
 
@@ -102,6 +101,6 @@ bun add @aihu/magna
102
101
 
103
102
  MIT — see [LICENSE](../../LICENSE).
104
103
 
105
- <sub><i>Auto-generated against `@aihu/magna@0.2.6`.</i></sub>
104
+ <sub><i>Auto-generated against `@aihu/magna@0.2.8`.</i></sub>
106
105
 
107
106
  <!-- END_AUTOGEN: license -->
package/dist/codegen.js CHANGED
@@ -1,3 +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=new Set([`__proto__`,`constructor`,`prototype`]),f=t.split(`.`);if(f.some(e=>d.has(e)))throw Error(`setBuildFlag: unsafe key segment in "${t}"`);let p=s;for(let e=0;e<f.length-1;e++){let t=f[e];(typeof p[t]!=`object`||p[t]===null||Array.isArray(p[t]))&&(p[t]={}),p=p[t]}let m=f[f.length-1];p[m]=n;let h=o(c(e),`build-flags.json`);l(i(h)),r(h,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(`
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=o(a,`build-flags.json`),d=u(s,{}),f=t.split(`.`),p=d;for(let e=0;e<f.length;e++){let r=f[e];if(r===`__proto__`||r===`constructor`||r===`prototype`)throw Error(`setBuildFlag: unsafe key segment '${r}' in "${t}"`);if(e===f.length-1){p[r]=n;break}let i=Object.hasOwn(p,r)?p[r]:void 0;(typeof i!=`object`||!i||Array.isArray(i))&&(p[r]={}),p=p[r]}l(i(s)),r(s,JSON.stringify(d,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
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
3
  //# sourceMappingURL=codegen.js.map
@@ -1 +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. `key` is a public API\n // parameter (exported function) — reject __proto__/constructor/prototype\n // segments so a future caller can't pollute Object.prototype across the\n // process (CodeQL js/prototype-pollution-utility). Every CURRENT caller\n // passes a hardcoded literal ('magna.untyped'), but the guard costs\n // nothing and the contract itself accepts an arbitrary string.\n const UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype'])\n const segments = key.split('.')\n if (segments.some((seg) => UNSAFE_KEYS.has(seg))) {\n throw new Error(`setBuildFlag: unsafe key segment in \"${key}\"`)\n }\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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"}
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 the dot-notation segments and deep-merge (CodeQL\n // js/prototype-pollution-utility). Two hazards, both checked per segment\n // rather than up front, so the guard sits directly on the control flow that\n // reaches the assignment:\n //\n // 1. `__proto__` / `constructor` / `prototype` as a segment. `key` is a\n // public API parameter of an exported function, and every current\n // caller passes the literal 'magna.untyped' — but the contract accepts\n // an arbitrary string, and `setBuildFlag(dir, '__proto__.x', v)` walks\n // `cursor.__proto__` straight onto Object.prototype and assigns there,\n // poisoning every object in the build process.\n // 2. Descending through the PROTOTYPE CHAIN. `typeof cursor[seg]` reads\n // inherited properties too, so if anything else in the process had\n // already polluted `Object.prototype.magna`, the old walk skipped\n // creating an own `magna` and merged into the shared prototype object\n // instead — the flag silently never reached build-flags.json.\n // `Object.hasOwn` keeps the walk on own properties only.\n const segments = key.split('.')\n let cursor: Record<string, unknown> = root\n\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i] as string\n if (seg === '__proto__' || seg === 'constructor' || seg === 'prototype') {\n throw new Error(`setBuildFlag: unsafe key segment '${seg}' in \"${key}\"`)\n }\n if (i === segments.length - 1) {\n cursor[seg] = value\n break\n }\n const existing = Object.hasOwn(cursor, seg) ? cursor[seg] : undefined\n if (typeof existing !== 'object' || existing === null || Array.isArray(existing)) {\n cursor[seg] = {}\n }\n cursor = cursor[seg] as Record<string, unknown>\n }\n\n ensureDir(dirname(filePath))\n writeFileSync(filePath, 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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"}
@@ -1 +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"}
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;;;cCaT,eAAA,EAAe,YAAA,CAAA,UAAA;;;;;;;;;;ADbN;;;;ACatB;;iBCLgB,gBAAA,CAAiB,OAAA,EAAS,kBAAA,GAAqB,UAAU;;;;;ADKzE;;;;AAA4B;;;;ACL5B;;;;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;;;;ACatB;;iBGAgB,oBAAA,GAAA,CAAA,GAA2B,uBAAuB,CAAC,CAAA"}
package/dist/index.js.map CHANGED
@@ -1 +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"}
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 * \"App root\" is a concrete seam: `createApp({ context: () => … })`\n * (`AppConfig.context`, @aihu/app). `provide()` is component-scoped, so a bare\n * call at module top level or elsewhere in `main.ts` lands in NO scope and\n * every `inject` silently returns `undefined`; the `context` callback runs\n * inside the app-root context scope, where it takes effect. Under the\n * standalone `<router>` SFC path, provide from an ancestor component's setup.\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,CC3BA,MAAa,EAAkB,EAA0B,ECLzD,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aihu/magna",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "aihu bridge for Magna GraphQL — dep-free fetch, resource composition, JWT relay",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -29,14 +29,11 @@
29
29
  "prepublishOnly": "bun run build"
30
30
  },
31
31
  "dependencies": {
32
- "@aihu/signals": "0.5.0",
32
+ "@aihu/signals": "^0.5.1",
33
33
  "@aihu/plugin": "0.1.0",
34
34
  "@aihu/context": "0.2.0",
35
35
  "@aihu-plugin/data": "2.0.5"
36
36
  },
37
- "optionalDependencies": {
38
- "@aihu/magna-gqlmin": "^0.2.0"
39
- },
40
37
  "devDependencies": {
41
38
  "rolldown": "^1.0.0-rc.17",
42
39
  "rolldown-plugin-dts": "^0.23.2",
@@ -45,11 +42,11 @@
45
42
  },
46
43
  "repository": {
47
44
  "type": "git",
48
- "url": "git+https://github.com/fellwork/aihu.git",
45
+ "url": "git+https://github.com/aihu-project/aihu.git",
49
46
  "directory": "packages/magna"
50
47
  },
51
- "homepage": "https://github.com/fellwork/aihu/tree/main/packages/magna#readme",
52
- "bugs": "https://github.com/fellwork/aihu/issues",
48
+ "homepage": "https://github.com/aihu-project/aihu/tree/main/packages/magna#readme",
49
+ "bugs": "https://github.com/aihu-project/aihu/issues",
53
50
  "publishConfig": {
54
51
  "access": "public"
55
52
  }