@junojs/core 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sources":["../src/cli/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * JunoJS CLI — Scaffolding & Manifest\n *\n * Commands:\n * juno new <project> — Create a new JunoJS project\n * juno generate component <name> — Generate a component (.ts + .html)\n * juno generate service <name> — Generate a service class\n * juno manifest — Generate junojs.manifest.json\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\n// ─── Main Router ────────────────────────────────────────────\n\nswitch (command) {\n case 'new':\n createProject(args[1]);\n break;\n case 'generate':\n case 'g':\n generate(args[1], args[2]);\n break;\n case 'manifest':\n generateManifest();\n break;\n default:\n printHelp();\n}\n\n// ─── Commands ───────────────────────────────────────────────\n\nfunction createProject(name?: string) {\n if (!name) {\n console.error('Usage: juno new <project-name>');\n process.exit(1);\n }\n\n const dir = path.resolve(process.cwd(), name);\n if (fs.existsSync(dir)) {\n console.error(`Directory \"${name}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n⚡ Creating JunoJS project: ${name}\\n`);\n\n // Create directory structure\n const dirs = [\n '',\n 'src',\n 'src/core',\n 'src/common',\n 'src/components',\n 'src/services',\n ];\n for (const d of dirs) {\n fs.mkdirSync(path.join(dir, d), { recursive: true });\n }\n\n // package.json\n writeFile(dir, 'package.json', JSON.stringify({\n name,\n version: '0.1.0',\n private: true,\n type: 'module',\n scripts: {\n dev: 'vite',\n build: 'tsc && vite build',\n preview: 'vite preview',\n types: 'ts-node scripts/meta-compiler.ts',\n },\n dependencies: {\n '@junojs/core': '^0.1.0',\n 'reflect-metadata': '^0.2.1',\n },\n devDependencies: {\n typescript: '^5.2.2',\n vite: '^5.4.0',\n 'ts-node': '^10.9.0',\n },\n }, null, 2));\n\n // tsconfig.json\n writeFile(dir, 'tsconfig.json', JSON.stringify({\n compilerOptions: {\n target: 'ESNext',\n module: 'ESNext',\n experimentalDecorators: true,\n emitDecoratorMetadata: true,\n moduleResolution: 'bundler',\n strict: true,\n outDir: 'dist',\n lib: ['ESNext', 'DOM', 'DOM.Iterable'],\n skipLibCheck: true,\n esModuleInterop: true,\n },\n include: ['src', 'main.ts'],\n }, null, 2));\n\n // index.html\n writeFile(dir, 'index.html', `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n</head>\n<body>\n <app-root></app-root>\n <script type=\"module\" src=\"/main.ts\"></script>\n</body>\n</html>`);\n\n // main.ts\n writeFile(dir, 'main.ts', `import 'reflect-metadata';\nimport { Component, State, bootstrap } from './src/core';\n\n@Component({ tag: 'app-root' })\nclass AppRoot {\n @State() message: string = 'Welcome to ${name}!';\n\n template = \\`\n <h1>{message}</h1>\n \\`;\n}\n\nbootstrap(AppRoot);\n`);\n\n // junojs.manifest.json\n writeFile(dir, 'junojs.manifest.json', JSON.stringify({\n name,\n version: '0.1.0',\n framework: '@junojs/core',\n generatedAt: new Date().toISOString(),\n structure: {\n components: 'src/components/',\n services: 'src/services/',\n core: 'src/core/',\n common: 'src/common/',\n },\n entry: 'main.ts',\n discovered: {\n components: [],\n services: [],\n },\n }, null, 2));\n\n console.log(' ✅ Project scaffolded successfully!');\n console.log(`\\n Next steps:`);\n console.log(` cd ${name}`);\n console.log(` npm install`);\n console.log(` npm run dev\\n`);\n}\n\nfunction generate(type?: string, name?: string) {\n if (!type || !name) {\n console.error('Usage: juno generate <component|service> <name>');\n process.exit(1);\n }\n\n switch (type) {\n case 'component':\n case 'c':\n generateComponent(name);\n break;\n case 'service':\n case 's':\n generateService(name);\n break;\n default:\n console.error(`Unknown generator: \"${type}\". Use \"component\" or \"service\".`);\n process.exit(1);\n }\n}\n\nfunction generateComponent(name: string) {\n const kebab = toKebab(name);\n const pascal = toPascal(name);\n const dir = path.resolve(process.cwd(), 'src', 'components', kebab);\n\n fs.mkdirSync(dir, { recursive: true });\n\n // TypeScript file\n writeFile(dir, `${kebab}.ts`, `import { Component, State } from '../../core/decorators';\n\n@Component({\n tag: '${kebab}',\n templateUrl: './src/components/${kebab}/${kebab}.html',\n})\nexport class ${pascal} {\n @State() title: string = '${pascal} works!';\n\n onInit() {\n // Async data fetching\n }\n\n onRender(el: HTMLElement) {\n // Post-render DOM access\n }\n\n onDestroy() {\n // Cleanup\n }\n}\n`);\n\n // HTML template\n writeFile(dir, `${kebab}.html`, `<div class=\"${kebab}\">\n <h2>{title}</h2>\n</div>\n`);\n\n console.log(`\\n⚡ Generated component: <${kebab}>`);\n console.log(` → ${dir}/${kebab}.ts`);\n console.log(` → ${dir}/${kebab}.html\\n`);\n}\n\nfunction generateService(name: string) {\n const kebab = toKebab(name);\n const pascal = toPascal(name);\n const dir = path.resolve(process.cwd(), 'src', 'services');\n\n fs.mkdirSync(dir, { recursive: true });\n\n writeFile(dir, `${kebab}.service.ts`, `/**\n * ${pascal}Service — Singleton\n */\nexport class ${pascal}Service {\n private static _instance: ${pascal}Service;\n\n static get instance(): ${pascal}Service {\n if (!${pascal}Service._instance) {\n ${pascal}Service._instance = new ${pascal}Service();\n }\n return ${pascal}Service._instance;\n }\n\n // Add your service methods here\n}\n`);\n\n console.log(`\\n⚡ Generated service: ${pascal}Service`);\n console.log(` → ${dir}/${kebab}.service.ts\\n`);\n}\n\nfunction generateManifest() {\n const cwd = process.cwd();\n const pkgPath = path.join(cwd, 'package.json');\n\n let name = 'junojs-app';\n let version = '0.1.0';\n\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n name = pkg.name || name;\n version = pkg.version || version;\n }\n\n // Discover components and services\n const components = discoverFiles(path.join(cwd, 'src', 'components'), '.ts');\n const services = discoverFiles(path.join(cwd, 'src', 'services'), '.service.ts');\n\n const manifest = {\n name,\n version,\n framework: '@junojs/core',\n generatedAt: new Date().toISOString(),\n structure: {\n components: 'src/components/',\n services: 'src/services/',\n core: 'src/core/',\n common: 'src/common/',\n },\n entry: 'main.ts',\n discovered: {\n components,\n services,\n },\n };\n\n const outPath = path.join(cwd, 'junojs.manifest.json');\n fs.writeFileSync(outPath, JSON.stringify(manifest, null, 2), 'utf-8');\n console.log(`\\n⚡ Generated manifest: ${outPath}`);\n console.log(` → ${components.length} component(s), ${services.length} service(s)\\n`);\n}\n\n// ─── Utilities ──────────────────────────────────────────────\n\nfunction toKebab(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\nfunction toPascal(name: string): string {\n return name\n .replace(/[-_\\s]+(.)/g, (_, c) => c.toUpperCase())\n .replace(/^(.)/, (_, c) => c.toUpperCase());\n}\n\nfunction writeFile(dir: string, filename: string, content: string): void {\n const filePath = path.join(dir, filename);\n fs.writeFileSync(filePath, content, 'utf-8');\n}\n\nfunction discoverFiles(dir: string, ext: string): string[] {\n if (!fs.existsSync(dir)) return [];\n const files: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n files.push(...discoverFiles(path.join(dir, entry.name), ext));\n } else if (entry.name.endsWith(ext)) {\n files.push(path.relative(process.cwd(), path.join(dir, entry.name)));\n }\n }\n return files;\n}\n\nfunction printHelp() {\n console.log(`\n ⚡ JunoJS CLI v1.0\n\n Usage:\n juno new <project> Create a new JunoJS project\n juno generate component <name> Generate a component (.ts + .html)\n juno generate service <name> Generate a service class\n juno manifest Generate junojs.manifest.json\n\n Shortcuts:\n juno g c <name> → generate component\n juno g s <name> → generate service\n`);\n}\n"],"names":["args","command","createProject","generate","generateManifest","printHelp","name","dir","path","fs","dirs","d","writeFile","type","generateComponent","generateService","kebab","toKebab","pascal","toPascal","cwd","pkgPath","version","pkg","components","discoverFiles","services","manifest","outPath","_","c","filename","content","filePath","ext","files","entry"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../src/cli/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * JunoJS CLI — Scaffolding & Manifest\n *\n * Commands:\n * juno new <project> — Create a new JunoJS project\n * juno generate component <name> — Generate a component (.ts + .html)\n * juno generate service <name> — Generate a service class\n * juno manifest — Generate junojs.manifest.json\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\n// ─── Main Router ────────────────────────────────────────────\n\nswitch (command) {\n case 'new':\n createProject(args[1]);\n break;\n case 'generate':\n case 'g':\n generate(args[1], args[2]);\n break;\n case 'manifest':\n generateManifest();\n break;\n default:\n printHelp();\n}\n\n// ─── Commands ───────────────────────────────────────────────\n\nfunction createProject(name?: string) {\n if (!name) {\n console.error('Usage: juno new <project-name>');\n process.exit(1);\n }\n\n const dir = path.resolve(process.cwd(), name);\n if (fs.existsSync(dir)) {\n console.error(`Directory \"${name}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n⚡ Creating JunoJS project: ${name}\\n`);\n\n // Create directory structure\n const dirs = [\n '',\n 'src',\n 'src/core',\n 'src/common',\n 'src/components',\n 'src/services',\n ];\n for (const d of dirs) {\n fs.mkdirSync(path.join(dir, d), { recursive: true });\n }\n\n // package.json\n writeFile(dir, 'package.json', JSON.stringify({\n name,\n version: '0.1.0',\n private: true,\n type: 'module',\n scripts: {\n dev: 'vite',\n build: 'tsc && vite build',\n preview: 'vite preview',\n types: 'ts-node scripts/meta-compiler.ts',\n },\n dependencies: {\n '@junojs/core': '^0.1.0',\n 'reflect-metadata': '^0.2.1',\n },\n devDependencies: {\n typescript: '^5.2.2',\n vite: '^5.4.0',\n 'ts-node': '^10.9.0',\n },\n }, null, 2));\n\n // tsconfig.json\n writeFile(dir, 'tsconfig.json', JSON.stringify({\n compilerOptions: {\n target: 'ESNext',\n module: 'ESNext',\n experimentalDecorators: true,\n emitDecoratorMetadata: true,\n moduleResolution: 'bundler',\n strict: true,\n outDir: 'dist',\n lib: ['ESNext', 'DOM', 'DOM.Iterable'],\n skipLibCheck: true,\n esModuleInterop: true,\n },\n include: ['src', 'main.ts'],\n }, null, 2));\n\n // index.html\n writeFile(dir, 'index.html', `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n</head>\n<body>\n <app-root></app-root>\n <script type=\"module\" src=\"/main.ts\"></script>\n</body>\n</html>`);\n\n // main.ts\n writeFile(dir, 'main.ts', `import 'reflect-metadata';\nimport { Component, State, bootstrap } from './src/core';\n\n@Component({ tag: 'app-root' })\nclass AppRoot {\n @State() message: string = 'Welcome to ${name}!';\n\n template = \\`\n <h1>{message}</h1>\n \\`;\n}\n\nbootstrap(AppRoot);\n`);\n\n // junojs.manifest.json\n writeFile(dir, 'junojs.manifest.json', JSON.stringify({\n name,\n version: '0.1.0',\n framework: '@junojs/core',\n generatedAt: new Date().toISOString(),\n structure: {\n components: 'src/components/',\n services: 'src/services/',\n core: 'src/core/',\n common: 'src/common/',\n },\n entry: 'main.ts',\n discovered: {\n components: [],\n services: [],\n },\n }, null, 2));\n\n console.log(' ✅ Project scaffolded successfully!');\n console.log(`\\n Next steps:`);\n console.log(` cd ${name}`);\n console.log(` npm install`);\n console.log(` npm run dev\\n`);\n}\n\nfunction generate(type?: string, name?: string) {\n if (!type || !name) {\n console.error('Usage: juno generate <component|service> <name>');\n process.exit(1);\n }\n\n switch (type) {\n case 'component':\n case 'c':\n generateComponent(name);\n break;\n case 'service':\n case 's':\n generateService(name);\n break;\n default:\n console.error(`Unknown generator: \"${type}\". Use \"component\" or \"service\".`);\n process.exit(1);\n }\n}\n\nfunction generateComponent(name: string) {\n const kebab = toKebab(name);\n const pascal = toPascal(name);\n const dir = path.resolve(process.cwd(), 'src', 'components', kebab);\n\n fs.mkdirSync(dir, { recursive: true });\n\n // TypeScript file\n writeFile(dir, `${kebab}.ts`, `import { Component, State } from '../../core/decorators';\n\n@Component({\n tag: '${kebab}',\n templateUrl: './src/components/${kebab}/${kebab}.html',\n})\nexport class ${pascal} {\n @State() title: string = '${pascal} works!';\n\n onInit() {\n // Async data fetching\n }\n\n onRender(el: HTMLElement) {\n // Post-render DOM access\n }\n\n onDestroy() {\n // Cleanup\n }\n}\n`);\n\n // HTML template\n writeFile(dir, `${kebab}.html`, `<div class=\"${kebab}\">\n <h2>{title}</h2>\n</div>\n`);\n\n console.log(`\\n⚡ Generated component: <${kebab}>`);\n console.log(` → ${dir}/${kebab}.ts`);\n console.log(` → ${dir}/${kebab}.html\\n`);\n}\n\nfunction generateService(name: string) {\n const kebab = toKebab(name);\n const pascal = toPascal(name);\n const dir = path.resolve(process.cwd(), 'src', 'services');\n\n fs.mkdirSync(dir, { recursive: true });\n\n writeFile(dir, `${kebab}.service.ts`, `/**\n * ${pascal}Service — Singleton\n */\nexport class ${pascal}Service {\n private static _instance: ${pascal}Service;\n\n static get instance(): ${pascal}Service {\n if (!${pascal}Service._instance) {\n ${pascal}Service._instance = new ${pascal}Service();\n }\n return ${pascal}Service._instance;\n }\n\n // Add your service methods here\n}\n`);\n\n console.log(`\\n⚡ Generated service: ${pascal}Service`);\n console.log(` → ${dir}/${kebab}.service.ts\\n`);\n}\n\nfunction generateManifest() {\n const cwd = process.cwd();\n const pkgPath = path.join(cwd, 'package.json');\n\n let name = 'junojs-app';\n let version = '0.1.0';\n\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n name = pkg.name || name;\n version = pkg.version || version;\n }\n\n // Discover components and services\n const components = discoverFiles(path.join(cwd, 'src', 'components'), '.ts');\n const services = discoverFiles(path.join(cwd, 'src', 'services'), '.service.ts');\n\n const manifest = {\n name,\n version,\n framework: '@junojs/core',\n generatedAt: new Date().toISOString(),\n structure: {\n components: 'src/components/',\n services: 'src/services/',\n core: 'src/core/',\n common: 'src/common/',\n },\n entry: 'main.ts',\n discovered: {\n components,\n services,\n },\n };\n\n const outPath = path.join(cwd, 'junojs.manifest.json');\n fs.writeFileSync(outPath, JSON.stringify(manifest, null, 2), 'utf-8');\n console.log(`\\n⚡ Generated manifest: ${outPath}`);\n console.log(` → ${components.length} component(s), ${services.length} service(s)\\n`);\n}\n\n// ─── Utilities ──────────────────────────────────────────────\n\nfunction toKebab(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\nfunction toPascal(name: string): string {\n return name\n .replace(/[-_\\s]+(.)/g, (_, c) => c.toUpperCase())\n .replace(/^(.)/, (_, c) => c.toUpperCase());\n}\n\nfunction writeFile(dir: string, filename: string, content: string): void {\n const filePath = path.join(dir, filename);\n fs.writeFileSync(filePath, content, 'utf-8');\n}\n\nfunction discoverFiles(dir: string, ext: string): string[] {\n if (!fs.existsSync(dir)) return [];\n const files: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n files.push(...discoverFiles(path.join(dir, entry.name), ext));\n } else if (entry.name.endsWith(ext)) {\n files.push(path.relative(process.cwd(), path.join(dir, entry.name)));\n }\n }\n return files;\n}\n\nfunction printHelp() {\n console.log(`\n ⚡ JunoJS CLI v1.0\n\n Usage:\n juno new <project> Create a new JunoJS project\n juno generate component <name> Generate a component (.ts + .html)\n juno generate service <name> Generate a service class\n juno manifest Generate junojs.manifest.json\n\n Shortcuts:\n juno g c <name> → generate component\n juno g s <name> → generate service\n`);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/core/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAO1B,wBAAsB,SAAS,CAAC,cAAc,EAAE,GAAG,iBA6VlD"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/core/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAO1B,wBAAsB,SAAS,CAAC,cAAc,EAAE,GAAG,iBAqXlD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bootstrap.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.test.d.ts","sourceRoot":"","sources":["../../src/core/bootstrap.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dom.bench.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.bench.d.ts","sourceRoot":"","sources":["../../src/core/dom.bench.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dom.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.test.d.ts","sourceRoot":"","sources":["../../src/core/dom.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reactivity.bench.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactivity.bench.d.ts","sourceRoot":"","sources":["../../src/core/reactivity.bench.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"reactivity.d.ts","sourceRoot":"","sources":["../../src/core/reactivity.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAG1B,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,IAAI,OA8BtE"}
1
+ {"version":3,"file":"reactivity.d.ts","sourceRoot":"","sources":["../../src/core/reactivity.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAG1B,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,IAAI,OAsCtE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reactivity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactivity.test.d.ts","sourceRoot":"","sources":["../../src/core/reactivity.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=template-url.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-url.test.d.ts","sourceRoot":"","sources":["../../src/core/template-url.test.ts"],"names":[],"mappings":""}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var U=Object.defineProperty;var V=(r,t,e)=>t in r?U(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var h=(r,t,e)=>V(r,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("reflect-metadata");function D(r){return t=>{r.shadow===void 0&&(r.shadow=!0),Reflect.defineMetadata("nf:config",r,t)}}function H(){return(r,t)=>{const e=Reflect.getMetadata("nf:states",r)||[];e.push(t),Reflect.defineMetadata("nf:states",e,r)}}function F(){return(r,t)=>{const e=Reflect.getMetadata("nf:inputs",r)||[];e.push(t),Reflect.defineMetadata("nf:inputs",e,r)}}function J(r){return(t,e)=>{const s=Reflect.getMetadata("nf:params",t)||[];s.push({key:e,paramName:r||e}),Reflect.defineMetadata("nf:params",s,t)}}function W(r){return(t,e)=>{Reflect.defineMetadata("nf:inject",r,t,e)}}function z(){return(r,t)=>{const e=Reflect.getMetadata("nf:transforms",r)||[];e.push(t),Reflect.defineMetadata("nf:transforms",e,r)}}function K(){return(r,t)=>{const e=Reflect.getMetadata("nf:actions",r)||[];e.push(t),Reflect.defineMetadata("nf:actions",e,r)}}function Z(r){return(t,e)=>{const s=Reflect.getMetadata("nf:provides",t)||[];s.push({key:r,property:e}),Reflect.defineMetadata("nf:provides",s,t)}}function G(r){return(t,e)=>{const s=Reflect.getMetadata("nf:injects",t)||[];s.push({key:r,property:e}),Reflect.defineMetadata("nf:injects",s,t)}}function Q(r){return t=>{const e=Reflect.getMetadata("nf:refine",t)||[];e.push(r),Reflect.defineMetadata("nf:refine",e,t)}}function X(r,t){return(e,s)=>{const n=Reflect.getMetadata("nf:validates",e)||[];n.push({key:s,predicate:r,message:t}),Reflect.defineMetadata("nf:validates",n,e)}}function B(r){return(t,e)=>{Reflect.defineMetadata("nf:intercept",r,t,e)}}function Y(r){return t=>{Reflect.defineMetadata("nf:canActivate",r,t)}}function tt(){return(r,t)=>{const e=Reflect.getMetadata("nf:host-properties",r)||[];e.push(t),Reflect.defineMetadata("nf:host-properties",e,r)}}function et(r){return t=>{Reflect.defineMetadata("nf:schema",r,t)}}function st(r="local"){return(t,e)=>{const s=Reflect.getMetadata("nf:persist",t)||[];s.push({property:e,storage:r,key:`nf:${t.constructor.name}:${e}`}),Reflect.defineMetadata("nf:persist",s,t)}}function I(r){if(!(typeof window>"u"))return r==="session"?window.sessionStorage:window.localStorage}function nt(r){const t=Reflect.getMetadata("nf:persist",r)||[];for(const e of t){const s=I(e.storage);if(!s)continue;const n=s.getItem(e.key);if(n!==null)try{r[e.property]=JSON.parse(n)}catch{r[e.property]=n}}}function rt(r,t,e){const n=(Reflect.getMetadata("nf:persist",r)||[]).find(i=>i.property===t);if(n){const i=I(n.storage);i&&i.setItem(n.key,JSON.stringify(e))}}function C(r,t){const e=Reflect.getMetadata("nf:states",r)||[],s=Reflect.getMetadata("nf:inputs",r)||[],n=[...e,...s,"errors"];let i;return i=new Proxy(r,{set(o,a,c){const l=o[a];return o[a]=c,n.includes(a)&&l!==c&&(rt(o,a,c),t()),!0},get(o,a){const c=o[a];return typeof c=="function"?c.bind(i):c}}),i}class L{static render(t,e){const i=new DOMParser().parseFromString(`<div>${t}</div>`,"text/html").body.firstElementChild;return i?(this.processNode(i,e),i):document.createElement("div")}static processNode(t,e){var c,l,f,p;if(t.nodeType===Node.TEXT_NODE){t.textContent=this.interpolate(t.textContent||"",e);return}if(t.nodeType!==Node.ELEMENT_NODE)return;const s=t,n=s.tagName.toLowerCase();if(n==="for"){const m=(((c=s.getAttribute("each"))==null?void 0:c.trim())||"").replace(/^\{/,"").replace(/\}$/,"").match(/(?:\(\s*([a-zA-Z_$]\w*)\s*,\s*([a-zA-Z_$]\w*)\s*\)|([a-zA-Z_$]\w*))\s+in\s+(.+)/);if(m){const g=m[1]||m[3],y=m[2],v=m[4],P=this.evaluateExpression(v,e),w=document.createDocumentFragment();Array.isArray(P)&&P.forEach((E,O)=>{const S=Object.create(e);S[g]=E,y&&(S[y]=O);const _=s.cloneNode(!0);for(Array.from(_.childNodes).forEach(q=>this.processNode(q,S));_.firstChild;)w.appendChild(_.firstChild)}),(l=s.parentNode)==null||l.replaceChild(w,s)}return}if(n==="if"){const d=(((f=s.getAttribute("condition"))==null?void 0:f.trim())||"").replace(/^\{/,"").replace(/\}$/,"");let m=!1;try{m=!!new Function("ctx",`with(ctx) { return ${d} }`)(e)}catch(w){console.error(`JunoEngine condition error: ${d}`,w)}const g=document.createDocumentFragment(),y=Array.from(s.childNodes),v=y.findIndex(w=>{var E;return((E=w.tagName)==null?void 0:E.toLowerCase())==="else"});(m?v!==-1?y.slice(0,v):y:v!==-1?Array.from(y[v].childNodes):[]).forEach(w=>{const E=w.cloneNode(!0);this.processNode(E,e),g.appendChild(E)}),(p=s.parentNode)==null||p.replaceChild(g,s);return}const i=Array.from(s.attributes),o=n.includes("-");i.forEach(u=>{const d=/^\{[^{}]+\}$/.test(u.value);if(o&&d){const m=u.value.slice(1,-1),g=this.evaluateExpression(m,e),y=u.name.replace(/-([a-z])/g,v=>v[1].toUpperCase());s[y]=g}else{const m=this.interpolate(u.value,e);m!==u.value&&s.setAttribute(u.name,m)}}),Array.from(s.childNodes).forEach(u=>this.processNode(u,e))}static evaluateExpression(t,e){const s=t.trim().split("|").map(c=>c.trim()),n=s[0],i=s[1],o=e.__transforms__||{};let a;try{/^[\w.]+$/.test(n)?a=n.split(".").reduce((c,l)=>c==null?void 0:c[l],e):a=new Function("ctx",`with(ctx) { return ${n} }`)(e)}catch{return}return i&&o[i]&&(a=o[i](a)),a}static interpolate(t,e){return t.replace(/\{((?:[^{}]|\{[^{}]*\})*)\}/g,(s,n)=>{const i=this.evaluateExpression(n,e);return i!==void 0?String(i):""})}}function it(r,t){let e;typeof t=="string"?e=new DOMParser().parseFromString(`<body>${t}</body>`,"text/html").body:e=t;const s=r instanceof ShadowRoot?r:document,n=s.activeElement,i=n&&n.id?`#${n.id}`:null,o=n?n.selectionStart:null,a=n?n.selectionEnd:null;if(j(r,e,r),i){const c=r.querySelector(i);c&&c!==s.activeElement&&(c.focus(),o!==null&&a!==null&&c.setSelectionRange(o,a))}}function j(r,t,e){const s=Array.from(r.childNodes),n=Array.from(t.childNodes),i=Math.max(s.length,n.length);for(let o=0;o<i;o++){const a=s[o],c=n[o];if(!a){r.appendChild(c);continue}if(!c){r.removeChild(a);continue}if(a.nodeType!==c.nodeType||a.tagName!==c.tagName){r.replaceChild(c,a);continue}if(a.nodeType===Node.TEXT_NODE){a.textContent!==c.textContent&&(a.textContent=c.textContent);continue}if(a.nodeType===Node.ELEMENT_NODE){const l=a,f=c,p=l.getAttributeNames(),u=f.getAttributeNames();for(const d of p)f.hasAttribute(d)||l.removeAttribute(d);for(const d of u){const m=f.getAttribute(d);l.getAttribute(d)!==m&&l.setAttribute(d,m);const g=d.replace(/-([a-z])/g,y=>y[1].toUpperCase());l.tagName.includes("-")&&f[g]!==void 0&&(l[g]=f[g])}if(l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement){const d=f.value||f.getAttribute("value")||"";l.value!==d&&(l.value=d)}(!l.tagName.includes("-")||l===e)&&j(l,f,e)}}}const M=class M{constructor(){h(this,"routes",[]);h(this,"listeners",[]);h(this,"lastTab",null);h(this,"lastParams",{});typeof window<"u"&&(window.addEventListener("popstate",()=>this.handleLocationChange()),window.addEventListener("hashchange",()=>this.handleLocationChange()))}static get instance(){return M._instance||(M._instance=new M),M._instance}register(t){this.routes=t}navigate(t,e=!0){if(typeof window>"u")return;const s=t.startsWith("/")?t:`/${t}`;window.location.pathname!==s&&(window.history.pushState({},"",s),e&&this.handleLocationChange())}onRouteMatch(t){return this.listeners.push(t),this.lastTab!==null?t(this.lastTab,this.lastParams):this.handleLocationChange(),()=>{this.listeners=this.listeners.filter(e=>e!==t)}}init(){this.handleLocationChange()}async handleLocationChange(){if(typeof window>"u")return;const t=window.location.pathname;let e,s={};for(const n of this.routes){if(n.path===t||`/${n.tab}`===t){e=n;break}if(n.path.includes("/:")){const i=n.path.split("/"),o=t.split("/");if(i.length===o.length){let a=!0;const c={};for(let l=0;l<i.length;l++)if(i[l].startsWith(":"))c[i[l].substring(1)]=o[l];else if(i[l]!==o[l]){a=!1;break}if(a){e=n,s=c;break}}}}if(e){if(e.canActivate)try{const n=await e.canActivate();if(n===!1)return;if(typeof n=="string"){this.navigate(n);return}}catch(n){console.error(`Route guard error on ${e.path}:`,n);return}e.title&&(document.title=e.title),this.notify(e.tab,s)}else if(t==="/"||t===""){const n=this.routes[0];n&&this.notify(n.tab,{})}}notify(t,e){this.lastTab=t,this.lastParams=e,this.listeners.forEach(s=>s(t,e))}get currentPath(){return typeof window<"u"?window.location.pathname:"/"}};h(M,"_instance");let N=M;async function at(r){const t=Reflect.getMetadata("nf:config",r);if(!t||!t.tag)throw new Error("Missing @Component decorator or tag!");customElements.define(t.tag,class extends HTMLElement{constructor(){super();h(this,"instance");h(this,"proxy");h(this,"target");h(this,"routeUnsubscribe");this.instance=new r,(Reflect.getMetadata("nf:host-properties",r.prototype)||[]).forEach(i=>{this.instance[i]=this}),(Reflect.getMetadata("nf:inputs",r.prototype)||[]).forEach(i=>{let o=this.hasOwnProperty(i)?this[i]:void 0;Object.defineProperty(this,i,{get:()=>this.proxy[i],set:a=>{this.proxy[i]=a,this.update()}}),o!==void 0&&(this.instance[i]=o)}),this.instance.errors||(this.instance.errors={}),this.instance.isValid||(this.instance.isValid=()=>{this.proxy.errors={};let i=!0;const o=Reflect.getMetadata("nf:schema",r),a=Reflect.getMetadata("nf:refine",r)||[],c=Reflect.getMetadata("nf:validates",r.prototype)||[],l=[];if(o&&typeof o.parse=="function"){const f=o.parse(this.proxy);f instanceof Promise?l.push(f.then(p=>{p.success||(i=!1,this.proxy.errors={...this.proxy.errors,...p.errors})})):f.success||(i=!1,this.proxy.errors={...this.proxy.errors,...f.errors})}for(const f of c){const p=this.proxy[f.key],u=f.predicate(p);u instanceof Promise?l.push(u.then(d=>{d||(i=!1,this.proxy.errors={...this.proxy.errors,[f.key]:f.message})})):u||(i=!1,this.proxy.errors={...this.proxy.errors,[f.key]:f.message})}for(const f of a){const p=f.validate(this.proxy);if(p instanceof Promise)l.push(p.then(u=>{if(!u){i=!1;const d=f.fields[f.fields.length-1];this.proxy.errors={...this.proxy.errors,[d]:f.message}}}));else if(!p){i=!1;const u=f.fields[f.fields.length-1];this.proxy.errors={...this.proxy.errors,[u]:f.message}}}return l.length>0?Promise.all(l).then(()=>i):i}),nt(this.instance),this.proxy=C(this.instance,()=>this.update()),t.shadow?this.target=this.shadowRoot||this.attachShadow({mode:"open"}):this.target=this;const n=(i,o)=>{let a=i.target;for(;a&&a!==this.parentElement;){const c=a.getAttribute(o);if(c){const l=c.match(/^(\w+)(?:\((.*)\))?$/);if(l){const[f,p,u]=l,d=this.proxy[p];if(typeof d=="function"){const m=Reflect.getMetadata("nf:intercept",this.instance,p);if(m){const g=m(this.proxy);if(g instanceof Promise){g.then(y=>{y===!1?(i.stopImmediatePropagation(),i.stopPropagation()):this.executeMethod(d,i,u)});return}else if(g===!1){i.stopImmediatePropagation(),i.stopPropagation();return}}this.executeMethod(d,i,u);return}}}if(a===this)break;a=a.parentElement}};this.target.addEventListener("click",i=>n(i,"@click")),this.target.addEventListener("input",i=>n(i,"@input"))}static get observedAttributes(){return Reflect.getMetadata("nf:inputs",r.prototype)||[]}attributeChangedCallback(s,n,i){i&&/^\{[^{}]+\}$/.test(i)||n!==i&&(this.proxy?(this.proxy[s]=i,this.update()):this.instance&&(this.instance[s]=i))}executeMethod(s,n,i){if(i!==void 0){const o=i.split(",").map(a=>(a=a.trim(),a==="e"||a==="$event"?n:a==="true"?!0:a==="false"?!1:!isNaN(Number(a))&&a!==""?Number(a):a.startsWith("'")&&a.endsWith("'")||a.startsWith('"')&&a.endsWith('"')?a.slice(1,-1):a));s.apply(this.proxy,o)}else s.call(this.proxy,n)}async connectedCallback(){const s=Reflect.getMetadata("nf:canActivate",r);if(s)try{const o=await s();if(o===!1)return;if(typeof o=="string"){N.instance.navigate(o);return}}catch(o){console.error("Guard evaluation failed:",o);return}if(this.instance.canActivate)try{const o=await this.instance.canActivate.call(this.proxy);if(o===!1)return;if(typeof o=="string"){N.instance.navigate(o);return}}catch(o){console.error("Lifecycle canActivate hook failed:",o);return}if(t.templateUrl){const o=await fetch(t.templateUrl);this.instance.template=await o.text()}const n=Reflect.getMetadata("nf:params",r.prototype)||[];if(n.length>0){const o=N.instance;this.routeUnsubscribe=o.onRouteMatch((a,c)=>{n.forEach(l=>{c[l.paramName]!==void 0&&this.proxy[l.key]!==c[l.paramName]&&(this.proxy[l.key]=c[l.paramName])})})}(Reflect.getMetadata("nf:injects",r.prototype)||[]).forEach(o=>{let a=this.parentElement;for(;a;){if(a.instance){const l=(Reflect.getMetadata("nf:provides",a.instance.constructor)||[]).find(f=>f.key===o.key);if(l){this.proxy[o.property]=a.proxy[l.property];break}}a=a.parentElement||a.getRootNode().host}}),this.instance.onInit&&await this.instance.onInit.call(this.proxy),this.update(),this.instance.onRender&&this.instance.onRender.call(this.proxy,this)}disconnectedCallback(){this.routeUnsubscribe&&this.routeUnsubscribe(),this.instance.onDestroy&&this.instance.onDestroy()}update(){const s=this.instance.template||"<div>No template</div>",n=Reflect.getMetadata("nf:transforms",this.instance)||[],i={};for(const c of n)typeof this.proxy[c]=="function"&&(i[c]=this.proxy[c]);const o=Object.create(this.proxy);o.__transforms__=i;const a=L.render(s,o);it(this.target,a)}})}const R=class R{constructor(){h(this,"middlewares",[])}static get instance(){return R._instance||(R._instance=new R),R._instance}addMiddleware(t){return this.middlewares.push(t),()=>{this.middlewares=this.middlewares.filter(e=>e!==t)}}handle(t){for(const e of this.middlewares)if(e(t)===!0)return;console.error("[JunoJS ErrorHandler] Unhandled error:",t.message,t)}static fromResponse(t,e){return{status:t.status,message:`HTTP ${t.status}: ${t.statusText}`,url:e,original:t}}static fromException(t){return t instanceof Error?{message:t.message,original:t}:{message:String(t),original:t}}};h(R,"_instance");let A=R;class ot{constructor(){h(this,"_initialValues",{});h(this,"_touched",{});queueMicrotask(()=>this._captureInitialValues())}isValid(){const t=this.getErrors();return Object.keys(t).length===0}getErrors(){const t=Reflect.getMetadata("nf:validators",this)||new Map,e={};return t.forEach((s,n)=>{const i=this[n],o=[];for(const a of s)a.validate(i,this)||o.push(a.message);o.length>0&&(e[n]=o)}),e}reset(){for(const[t,e]of Object.entries(this._initialValues))this[t]=e;this._touched={}}get dirty(){for(const[t,e]of Object.entries(this._initialValues))if(this[t]!==e)return!0;return!1}get touched(){return{...this._touched}}markTouched(t){this._touched[t]=!0}_captureInitialValues(){(Reflect.getMetadata("nf:validators",this)||new Map).forEach((e,s)=>{this._initialValues[s]=this[s]})}}function T(r,t,e){const s=Reflect.getMetadata("nf:validators",r)||new Map,n=s.get(t)||[];n.push(e),s.set(t,n),Reflect.defineMetadata("nf:validators",s,r)}function ct(r="This field is required"){return(t,e)=>{T(t,e,{name:"required",message:r,validate:s=>s!=null&&String(s).trim().length>0})}}function lt(r="Invalid email address"){return(t,e)=>{T(t,e,{name:"email",message:r,validate:s=>s?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(s)):!0})}}function ft(r,t){return(e,s)=>{T(e,s,{name:"match",message:t||`Must match ${r}`,validate:(n,i)=>n===i[r]})}}function dt(r,t="Invalid format"){return(e,s)=>{T(e,s,{name:"pattern",message:t,validate:n=>n?r.test(String(n)):!0})}}class b{constructor(){h(this,"rules",[]);h(this,"IS_REQUIRED",!1)}required(t="Required"){return this.IS_REQUIRED=!0,this.rules.push(e=>!e&&e!==0&&e!==!1?t:void 0),this}email(t="Invalid email"){return this.rules.push(e=>{if(e)return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(e))?void 0:t}),this}min(t,e){return this.rules.push(s=>{if(s)return String(s).length<t?e||`Min length ${t}`:void 0}),this}max(t,e){return this.rules.push(s=>{if(s)return String(s).length>t?e||`Max length ${t}`:void 0}),this}validate(t,e){for(const s of this.rules){const n=s(t,e);if(n)return n}}}class k{constructor(){h(this,"fields",{});h(this,"refines",[])}string(){return new b}number(){return new b}boolean(){return new b}shape(t){return this.fields=t,this}refine(t,e){return this.refines.push({validate:t,...e}),this}async parse(t){const e={};let s=!0;for(const[n,i]of Object.entries(this.fields)){const o=i.validate(t[n],t);o&&(e[n]=o,s=!1)}for(const n of this.refines){const i=n.validate(t);(i instanceof Promise?await i:i)||(e[n.path]=n.message,s=!1)}return{success:s,errors:s?void 0:e}}}const ut={string:()=>new b,number:()=>new b,boolean:()=>new b,object:r=>new k().shape(r)};class ht{constructor(){h(this,"requestInterceptors",[]);h(this,"responseInterceptors",[]);h(this,"errorHandler",null)}setErrorHandler(t){this.errorHandler=t}addRequestInterceptor(t){this.requestInterceptors.push(t)}addResponseInterceptor(t){this.responseInterceptors.push(t)}async get(t,e){return this.request("GET",t,void 0,e)}async post(t,e,s){return this.request("POST",t,e,s)}async put(t,e,s){return this.request("PUT",t,e,s)}async delete(t,e){return this.request("DELETE",t,void 0,e)}async patch(t,e,s){return this.request("PATCH",t,e,s)}async request(t,e,s,n){let i=e;if(n!=null&&n.params){const f=new URLSearchParams(n.params).toString();i+=(e.includes("?")?"&":"?")+f}const o={"Content-Type":"application/json",...(n==null?void 0:n.headers)||{}},a={method:t,headers:o};s!==void 0&&(a.body=JSON.stringify(s));const c=new AbortController;let l;n!=null&&n.signal&&n.signal.addEventListener("abort",()=>c.abort()),n!=null&&n.timeout&&n.timeout>0&&(l=setTimeout(()=>c.abort(),n.timeout)),a.signal=c.signal;for(const f of this.requestInterceptors){const p=f(i,a);p&&([i]=p,Object.assign(a,p[1]))}try{let f=await fetch(i,a);for(const u of this.responseInterceptors){const d=u(f);d&&(f=d)}if(!f.ok)throw this.errorHandler&&this.errorHandler.handle(A.fromResponse(f,i)),new Error(`HTTP ${f.status}: ${f.statusText}`);return(f.headers.get("content-type")||"").includes("application/json")?await f.json():await f.text()}finally{l!==void 0&&clearTimeout(l)}}}const x=class x{constructor(){h(this,"dictionaries",new Map);h(this,"_locale","en");h(this,"_onLocaleChange",[])}static get instance(){return x._instance||(x._instance=new x),x._instance}get locale(){return this._locale}addTranslations(t,e){const s=this.dictionaries.get(t)||{};this.dictionaries.set(t,{...s,...e})}setLocale(t){this.dictionaries.has(t)||console.warn(`[i18n] No translations registered for locale "${t}".`),this._locale=t;for(const e of this._onLocaleChange)e()}onLocaleChange(t){return this._onLocaleChange.push(t),()=>{this._onLocaleChange=this._onLocaleChange.filter(e=>e!==t)}}t(t,e){const s=this.dictionaries.get(this._locale);let n=s==null?void 0:s[t];if(n===void 0)return t;if(e)for(const[i,o]of Object.entries(e))n=n.replace(new RegExp(`\\{\\{${i}\\}\\}`,"g"),String(o));return n}get availableLocales(){return[...this.dictionaries.keys()]}};h(x,"_instance");let $=x;exports.Action=K;exports.CanActivate=Y;exports.Component=D;exports.Email=lt;exports.ErrorHandler=A;exports.FormModel=ot;exports.FormSchema=k;exports.HostElement=tt;exports.HttpClient=ht;exports.I18nService=$;exports.Inject=G;exports.Input=F;exports.Intercept=B;exports.JunoEngine=L;exports.Match=ft;exports.Param=J;exports.Pattern=dt;exports.Persist=st;exports.Provide=Z;exports.Refine=Q;exports.Required=ct;exports.RouterService=N;exports.Schema=et;exports.SchemaField=b;exports.State=H;exports.Transform=z;exports.Use=W;exports.Validate=X;exports.bootstrap=at;exports.createReactiveProxy=C;exports.s=ut;
2
- //# sourceMappingURL=index.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`reflect-metadata`);function e(e){return t=>{e.shadow===void 0&&(e.shadow=!0),Reflect.defineMetadata(`nf:config`,e,t)}}function t(){return(e,t)=>{let n=Reflect.getMetadata(`nf:states`,e)||[];n.push(t),Reflect.defineMetadata(`nf:states`,n,e)}}function n(){return(e,t)=>{let n=Reflect.getMetadata(`nf:inputs`,e)||[];n.push(t),Reflect.defineMetadata(`nf:inputs`,n,e)}}function r(e){return(t,n)=>{let r=Reflect.getMetadata(`nf:params`,t)||[];r.push({key:n,paramName:e||n}),Reflect.defineMetadata(`nf:params`,r,t)}}function i(e){return(t,n)=>{Reflect.defineMetadata(`nf:inject`,e,t,n)}}function a(){return(e,t)=>{let n=Reflect.getMetadata(`nf:transforms`,e)||[];n.push(t),Reflect.defineMetadata(`nf:transforms`,n,e)}}function o(){return(e,t)=>{let n=Reflect.getMetadata(`nf:actions`,e)||[];n.push(t),Reflect.defineMetadata(`nf:actions`,n,e)}}function s(e){return(t,n)=>{let r=Reflect.getMetadata(`nf:provides`,t)||[];r.push({key:e,property:n}),Reflect.defineMetadata(`nf:provides`,r,t)}}function c(e){return(t,n)=>{let r=Reflect.getMetadata(`nf:injects`,t)||[];r.push({key:e,property:n}),Reflect.defineMetadata(`nf:injects`,r,t)}}function l(e){return t=>{let n=Reflect.getMetadata(`nf:refine`,t)||[];n.push(e),Reflect.defineMetadata(`nf:refine`,n,t)}}function u(e,t){return(n,r)=>{let i=Reflect.getMetadata(`nf:validates`,n)||[];i.push({key:r,predicate:e,message:t}),Reflect.defineMetadata(`nf:validates`,i,n)}}function d(e){return(t,n)=>{Reflect.defineMetadata(`nf:intercept`,e,t,n)}}function f(e){return t=>{Reflect.defineMetadata(`nf:canActivate`,e,t)}}function p(){return(e,t)=>{let n=Reflect.getMetadata(`nf:host-properties`,e)||[];n.push(t),Reflect.defineMetadata(`nf:host-properties`,n,e)}}function m(e){return t=>{Reflect.defineMetadata(`nf:schema`,e,t)}}function h(e=`local`){return(t,n)=>{let r=Reflect.getMetadata(`nf:persist`,t)||[];r.push({property:n,storage:e,key:`nf:${t.constructor.name}:${n}`}),Reflect.defineMetadata(`nf:persist`,r,t)}}function g(e){if(!(typeof window>`u`))return e===`session`?window.sessionStorage:window.localStorage}function _(e){let t=Reflect.getMetadata(`nf:persist`,e)||[];for(let n of t){let t=g(n.storage);if(!t)continue;let r=t.getItem(n.key);if(r!==null)try{e[n.property]=JSON.parse(r)}catch{e[n.property]=r}}}function v(e,t,n){let r=(Reflect.getMetadata(`nf:persist`,e)||[]).find(e=>e.property===t);if(r){let e=g(r.storage);e&&e.setItem(r.key,JSON.stringify(n))}}function y(e,t){let n=Reflect.getMetadata(`nf:states`,e)||[],r=Reflect.getMetadata(`nf:inputs`,e)||[],i=[...n,...r,`errors`],a;return a=new Proxy(e,{set(e,n,r){let a=e[n];return e[n]=r,i.includes(n)&&a!==r&&(v(e,n,r),t()),!0},get(e,t){let n=e[t];return typeof n==`function`?(e.__boundMethods__||=new Map,e.__boundMethods__.has(t)||e.__boundMethods__.set(t,n.bind(a)),e.__boundMethods__.get(t)):n}}),a}var b=class{static render(e,t){let n=new DOMParser().parseFromString(`<div>${e}</div>`,`text/html`).body.firstElementChild;return n?(this.processNode(n,t),n):document.createElement(`div`)}static processNode(e,t){if(e.nodeType===Node.TEXT_NODE){e.textContent=this.interpolate(e.textContent||``,t);return}if(e.nodeType!==Node.ELEMENT_NODE)return;let n=e,r=n.tagName.toLowerCase();if(r===`for`){let e=(n.getAttribute(`each`)?.trim()||``).replace(/^\{/,``).replace(/\}$/,``).match(/(?:\(\s*([a-zA-Z_$]\w*)\s*,\s*([a-zA-Z_$]\w*)\s*\)|([a-zA-Z_$]\w*))\s+in\s+(.+)/);if(e){let r=e[1]||e[3],i=e[2],a=e[4],o=this.evaluateExpression(a,t),s=document.createDocumentFragment();Array.isArray(o)&&o.forEach((e,a)=>{let o=Object.create(t);o[r]=e,i&&(o[i]=a);let c=n.cloneNode(!0);for(Array.from(c.childNodes).forEach(e=>this.processNode(e,o));c.firstChild;)s.appendChild(c.firstChild)}),n.parentNode?.replaceChild(s,n)}return}if(r===`if`){let e=(n.getAttribute(`condition`)?.trim()||``).replace(/^\{/,``).replace(/\}$/,``),r=!1;try{r=!!Function(`ctx`,`with(ctx) { return ${e} }`)(t)}catch(t){console.error(`JunoEngine condition error: ${e}`,t)}let i=document.createDocumentFragment(),a=Array.from(n.childNodes),o=a.findIndex(e=>e.tagName?.toLowerCase()===`else`);(r?o===-1?a:a.slice(0,o):o===-1?[]:Array.from(a[o].childNodes)).forEach(e=>{let n=e.cloneNode(!0);this.processNode(n,t),i.appendChild(n)}),n.parentNode?.replaceChild(i,n);return}let i=Array.from(n.attributes),a=r.includes(`-`);i.forEach(e=>{let r=/^\{[^{}]+\}$/.test(e.value);if(a&&r){let r=e.value.slice(1,-1),i=this.evaluateExpression(r,t),a=e.name.replace(/-([a-z])/g,e=>e[1].toUpperCase());n[a]=i}else{let r=this.interpolate(e.value,t);r!==e.value&&n.setAttribute(e.name,r)}}),Array.from(n.childNodes).forEach(e=>this.processNode(e,t))}static evaluateExpression(e,t){let n=e.trim().split(`|`).map(e=>e.trim()),r=n[0],i=n[1],a=t.__transforms__||{},o;try{o=/^[\w.]+$/.test(r)?r.split(`.`).reduce((e,t)=>e?.[t],t):Function(`ctx`,`with(ctx) { return ${r} }`)(t)}catch{return}return i&&a[i]&&(o=a[i](o)),o}static interpolate(e,t){return e.replace(/\{((?:[^{}]|\{[^{}]*\})*)\}/g,(e,n)=>{let r=this.evaluateExpression(n,t);return r===void 0?``:String(r)})}};function x(e,t){let n;n=typeof t==`string`?new DOMParser().parseFromString(`<body>${t}</body>`,`text/html`).body:t;let r=e instanceof ShadowRoot?e:document,i=r.activeElement,a=i&&i.id?`#${i.id}`:null,o=i?i.selectionStart:null,s=i?i.selectionEnd:null;if(S(e,n,e),a){let t=e.querySelector(a);t&&t!==r.activeElement&&(t.focus(),o!==null&&s!==null&&t.setSelectionRange(o,s))}}function S(e,t,n){let r=Array.from(e.childNodes),i=Array.from(t.childNodes),a=Math.max(r.length,i.length);for(let t=0;t<a;t++){let a=r[t],o=i[t];if(!a){e.appendChild(o);continue}if(!o){e.removeChild(a);continue}if(a.nodeType!==o.nodeType||a.tagName!==o.tagName){e.replaceChild(o,a);continue}if(a.nodeType===Node.TEXT_NODE){a.textContent!==o.textContent&&(a.textContent=o.textContent);continue}if(a.nodeType===Node.ELEMENT_NODE){let e=a,t=o,r=e.getAttributeNames(),i=t.getAttributeNames();for(let n of r)t.hasAttribute(n)||e.removeAttribute(n);for(let n of i){let r=t.getAttribute(n);e.getAttribute(n)!==r&&e.setAttribute(n,r);let i=n.replace(/-([a-z])/g,e=>e[1].toUpperCase());e.tagName.includes(`-`)&&t[i]!==void 0&&e[i]!==t[i]&&(e[i]=t[i])}if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){let n=t.value||t.getAttribute(`value`)||``;e.value!==n&&(e.value=n)}(!e.tagName.includes(`-`)||e===n)&&S(e,t,n)}}}var C=class e{static _instance;routes=[];listeners=[];lastTab=null;lastParams={};static get instance(){return e._instance||=new e,e._instance}constructor(){typeof window<`u`&&(window.addEventListener(`popstate`,()=>this.handleLocationChange()),window.addEventListener(`hashchange`,()=>this.handleLocationChange()))}register(e){this.routes=e}navigate(e,t=!0){if(typeof window>`u`)return;let n=e.startsWith(`/`)?e:`/${e}`;window.location.pathname!==n&&(window.history.pushState({},``,n),t&&this.handleLocationChange())}onRouteMatch(e){return this.listeners.push(e),this.lastTab===null?this.handleLocationChange():e(this.lastTab,this.lastParams),()=>{this.listeners=this.listeners.filter(t=>t!==e)}}init(){this.handleLocationChange()}async handleLocationChange(){if(typeof window>`u`)return;let e=window.location.pathname,t,n={};for(let r of this.routes){if(r.path===e||`/${r.tab}`===e){t=r;break}if(r.path.includes(`/:`)){let i=r.path.split(`/`),a=e.split(`/`);if(i.length===a.length){let e=!0,o={};for(let t=0;t<i.length;t++)if(i[t].startsWith(`:`))o[i[t].substring(1)]=a[t];else if(i[t]!==a[t]){e=!1;break}if(e){t=r,n=o;break}}}}if(t){if(t.canActivate)try{let e=await t.canActivate();if(e===!1)return;if(typeof e==`string`){this.navigate(e);return}}catch(e){console.error(`Route guard error on ${t.path}:`,e);return}t.title&&(document.title=t.title),this.notify(t.tab,n)}else if(e===`/`||e===``){let e=this.routes[0];e&&this.notify(e.tab,{})}}notify(e,t){this.lastTab=e,this.lastParams=t,this.listeners.forEach(n=>n(e,t))}get currentPath(){return typeof window<`u`?window.location.pathname:`/`}};async function w(e){let t=Reflect.getMetadata(`nf:config`,e);if(!t||!t.tag)throw Error(`Missing @Component decorator or tag!`);customElements.define(t.tag,class extends HTMLElement{instance;proxy;target;routeUnsubscribe;static get observedAttributes(){return Reflect.getMetadata(`nf:inputs`,e.prototype)||[]}attributeChangedCallback(e,t,n){n&&/^\{[^{}]+\}$/.test(n)||t!==n&&(this.proxy?this.proxy[e]=n:this.instance&&(this.instance[e]=n,this.update()))}constructor(){super(),this.instance=new e,(Reflect.getMetadata(`nf:host-properties`,e.prototype)||[]).forEach(e=>{this.instance[e]=this}),(Reflect.getMetadata(`nf:inputs`,e.prototype)||[]).forEach(e=>{let t=this.hasOwnProperty(e)?this[e]:void 0;Object.defineProperty(this,e,{get:()=>this.proxy[e],set:t=>{this.proxy?.[e]!==t&&(this.proxy?this.proxy[e]=t:(this.instance[e]=t,this.update()))}}),t!==void 0&&(this.instance[e]=t)}),this.instance.errors||(this.instance.errors={}),this.instance.isValid||(this.instance.isValid=()=>{this.proxy.errors={};let t=!0,n=Reflect.getMetadata(`nf:schema`,e),r=Reflect.getMetadata(`nf:refine`,e)||[],i=Reflect.getMetadata(`nf:validates`,e.prototype)||[],a=[];if(n&&typeof n.parse==`function`){let e=n.parse(this.proxy);e instanceof Promise?a.push(e.then(e=>{e.success||(t=!1,this.proxy.errors={...this.proxy.errors,...e.errors})})):e.success||(t=!1,this.proxy.errors={...this.proxy.errors,...e.errors})}for(let e of i){let n=this.proxy[e.key],r=e.predicate(n);r instanceof Promise?a.push(r.then(n=>{n||(t=!1,this.proxy.errors={...this.proxy.errors,[e.key]:e.message})})):r||(t=!1,this.proxy.errors={...this.proxy.errors,[e.key]:e.message})}for(let e of r){let n=e.validate(this.proxy);if(n instanceof Promise)a.push(n.then(n=>{if(!n){t=!1;let n=e.fields[e.fields.length-1];this.proxy.errors={...this.proxy.errors,[n]:e.message}}}));else if(!n){t=!1;let n=e.fields[e.fields.length-1];this.proxy.errors={...this.proxy.errors,[n]:e.message}}}return a.length>0?Promise.all(a).then(()=>t):t}),_(this.instance),this.proxy=y(this.instance,()=>this.update()),t.shadow?this.target=this.shadowRoot||this.attachShadow({mode:`open`}):this.target=this;let n=(e,t)=>{let n=e.target;for(;n&&n!==this.parentElement;){let r=n.getAttribute(t);if(r){let t=r.match(/^(\w+)(?:\((.*)\))?$/);if(t){let[n,r,i]=t,a=this.proxy[r];if(typeof a==`function`){let t=Reflect.getMetadata(`nf:intercept`,this.instance,r);if(t){let n=t(this.proxy);if(n instanceof Promise){n.then(t=>{t===!1?(e.stopImmediatePropagation(),e.stopPropagation()):this.executeMethod(a,e,i)});return}else if(n===!1){e.stopImmediatePropagation(),e.stopPropagation();return}}this.executeMethod(a,e,i);return}}}if(n===this)break;n=n.parentElement}};this.target.addEventListener(`click`,e=>n(e,`@click`)),this.target.addEventListener(`input`,e=>n(e,`@input`))}executeMethod(e,t,n){if(n!==void 0){let r=n.split(`,`).map(e=>(e=e.trim(),e===`e`||e===`$event`?t:e===`true`?!0:e===`false`?!1:!isNaN(Number(e))&&e!==``?Number(e):e.startsWith(`'`)&&e.endsWith(`'`)||e.startsWith(`"`)&&e.endsWith(`"`)?e.slice(1,-1):e));e.apply(this.proxy,r)}else e.call(this.proxy,t)}async connectedCallback(){let n=Reflect.getMetadata(`nf:canActivate`,e);if(n)try{let e=await n();if(e===!1)return;if(typeof e==`string`){C.instance.navigate(e);return}}catch(e){console.error(`Guard evaluation failed:`,e);return}if(this.instance.canActivate)try{let e=await this.instance.canActivate.call(this.proxy);if(e===!1)return;if(typeof e==`string`){C.instance.navigate(e);return}}catch(e){console.error(`Lifecycle canActivate hook failed:`,e);return}if(t.templateUrl)try{let e=await fetch(t.templateUrl);if(!e.ok)throw Error(`Failed to fetch template: ${e.status} ${e.statusText}`);let n=e.headers.get(`content-type`),r=await e.text();n?.includes(`text/html`)&&r.includes(`<${t.tag}`)?(console.error(`Recursive template detected for ${t.tag}. Check if ${t.templateUrl} exists!`),this.instance.template=`<div style="color:red; padding: 20px; border: 1px solid red;">Recursive template detected for &lt;${t.tag}&gt;! Check URL: ${t.templateUrl}</div>`):this.instance.template=r}catch(e){console.error(`Juno ERROR: Failed to load template from ${t.templateUrl}`,e),this.instance.template=`<div style="color:red; padding: 10px; border: 1px solid red;">Error loading template from ${t.templateUrl}: ${e.message||e}</div>`}let r=Reflect.getMetadata(`nf:params`,e.prototype)||[];r.length>0&&(this.routeUnsubscribe=C.instance.onRouteMatch((e,t)=>{r.forEach(e=>{t[e.paramName]!==void 0&&this.proxy[e.key]!==t[e.paramName]&&(this.proxy[e.key]=t[e.paramName])})})),(Reflect.getMetadata(`nf:injects`,e.prototype)||[]).forEach(e=>{let t=this.parentElement;for(;t;){if(t.instance){let n=(Reflect.getMetadata(`nf:provides`,t.instance.constructor)||[]).find(t=>t.key===e.key);if(n){this.proxy[e.property]=t.proxy[n.property];break}}t=t.parentElement||t.getRootNode().host}}),this.instance.onInit&&await this.instance.onInit.call(this.proxy),this.update(),this.instance.onRender&&this.instance.onRender.call(this.proxy,this)}disconnectedCallback(){this.routeUnsubscribe&&this.routeUnsubscribe(),this.instance.onDestroy&&this.instance.onDestroy()}update(){let e=this.instance.template||`<div>No template</div>`,t=Reflect.getMetadata(`nf:transforms`,this.instance)||[],n={};for(let e of t)typeof this.proxy[e]==`function`&&(n[e]=this.proxy[e]);let r=Object.create(this.proxy);r.__transforms__=n;let i=b.render(e,r);x(this.target,i)}})}var T=class e{static _instance;static get instance(){return e._instance||=new e,e._instance}middlewares=[];addMiddleware(e){return this.middlewares.push(e),()=>{this.middlewares=this.middlewares.filter(t=>t!==e)}}handle(e){for(let t of this.middlewares)if(t(e)===!0)return;console.error(`[JunoJS ErrorHandler] Unhandled error:`,e.message,e)}static fromResponse(e,t){return{status:e.status,message:`HTTP ${e.status}: ${e.statusText}`,url:t,original:e}}static fromException(e){return e instanceof Error?{message:e.message,original:e}:{message:String(e),original:e}}},E=class{_initialValues={};_touched={};constructor(){queueMicrotask(()=>this._captureInitialValues())}isValid(){let e=this.getErrors();return Object.keys(e).length===0}getErrors(){let e=Reflect.getMetadata(`nf:validators`,this)||new Map,t={};return e.forEach((e,n)=>{let r=this[n],i=[];for(let t of e)t.validate(r,this)||i.push(t.message);i.length>0&&(t[n]=i)}),t}reset(){for(let[e,t]of Object.entries(this._initialValues))this[e]=t;this._touched={}}get dirty(){for(let[e,t]of Object.entries(this._initialValues))if(this[e]!==t)return!0;return!1}get touched(){return{...this._touched}}markTouched(e){this._touched[e]=!0}_captureInitialValues(){(Reflect.getMetadata(`nf:validators`,this)||new Map).forEach((e,t)=>{this._initialValues[t]=this[t]})}};function D(e,t,n){let r=Reflect.getMetadata(`nf:validators`,e)||new Map,i=r.get(t)||[];i.push(n),r.set(t,i),Reflect.defineMetadata(`nf:validators`,r,e)}function O(e=`This field is required`){return(t,n)=>{D(t,n,{name:`required`,message:e,validate:e=>e!=null&&String(e).trim().length>0})}}function k(e=`Invalid email address`){return(t,n)=>{D(t,n,{name:`email`,message:e,validate:e=>e?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(e)):!0})}}function A(e,t){return(n,r)=>{D(n,r,{name:`match`,message:t||`Must match ${e}`,validate:(t,n)=>t===n[e]})}}function j(e,t=`Invalid format`){return(n,r)=>{D(n,r,{name:`pattern`,message:t,validate:t=>t?e.test(String(t)):!0})}}var M=class{rules=[];IS_REQUIRED=!1;required(e=`Required`){return this.IS_REQUIRED=!0,this.rules.push(t=>!t&&t!==0&&t!==!1?e:void 0),this}email(e=`Invalid email`){return this.rules.push(t=>{if(t)return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(t))?void 0:e}),this}min(e,t){return this.rules.push(n=>{if(n)return String(n).length<e?t||`Min length ${e}`:void 0}),this}max(e,t){return this.rules.push(n=>{if(n)return String(n).length>e?t||`Max length ${e}`:void 0}),this}validate(e,t){for(let n of this.rules){let r=n(e,t);if(r)return r}}},N=class{fields={};refines=[];string(){return new M}number(){return new M}boolean(){return new M}shape(e){return this.fields=e,this}refine(e,t){return this.refines.push({validate:e,...t}),this}async parse(e){let t={},n=!0;for(let[r,i]of Object.entries(this.fields)){let a=i.validate(e[r],e);a&&(t[r]=a,n=!1)}for(let r of this.refines){let i=r.validate(e);(i instanceof Promise?await i:i)||(t[r.path]=r.message,n=!1)}return{success:n,errors:n?void 0:t}}},P={string:()=>new M,number:()=>new M,boolean:()=>new M,object:e=>new N().shape(e)},F=class{requestInterceptors=[];responseInterceptors=[];errorHandler=null;setErrorHandler(e){this.errorHandler=e}addRequestInterceptor(e){this.requestInterceptors.push(e)}addResponseInterceptor(e){this.responseInterceptors.push(e)}async get(e,t){return this.request(`GET`,e,void 0,t)}async post(e,t,n){return this.request(`POST`,e,t,n)}async put(e,t,n){return this.request(`PUT`,e,t,n)}async delete(e,t){return this.request(`DELETE`,e,void 0,t)}async patch(e,t,n){return this.request(`PATCH`,e,t,n)}async request(e,t,n,r){let i=t;if(r?.params){let e=new URLSearchParams(r.params).toString();i+=(t.includes(`?`)?`&`:`?`)+e}let a={method:e,headers:{"Content-Type":`application/json`,...r?.headers||{}}};n!==void 0&&(a.body=JSON.stringify(n));let o=new AbortController,s;r?.signal&&r.signal.addEventListener(`abort`,()=>o.abort()),r?.timeout&&r.timeout>0&&(s=setTimeout(()=>o.abort(),r.timeout)),a.signal=o.signal;for(let e of this.requestInterceptors){let t=e(i,a);t&&([i]=t,Object.assign(a,t[1]))}try{let e=await fetch(i,a);for(let t of this.responseInterceptors){let n=t(e);n&&(e=n)}if(!e.ok)throw this.errorHandler&&this.errorHandler.handle(T.fromResponse(e,i)),Error(`HTTP ${e.status}: ${e.statusText}`);return(e.headers.get(`content-type`)||``).includes(`application/json`)?await e.json():await e.text()}finally{s!==void 0&&clearTimeout(s)}}},I=class e{static _instance;static get instance(){return e._instance||=new e,e._instance}dictionaries=new Map;_locale=`en`;_onLocaleChange=[];get locale(){return this._locale}addTranslations(e,t){let n=this.dictionaries.get(e)||{};this.dictionaries.set(e,{...n,...t})}setLocale(e){this.dictionaries.has(e)||console.warn(`[i18n] No translations registered for locale "${e}".`),this._locale=e;for(let e of this._onLocaleChange)e()}onLocaleChange(e){return this._onLocaleChange.push(e),()=>{this._onLocaleChange=this._onLocaleChange.filter(t=>t!==e)}}t(e,t){let n=this.dictionaries.get(this._locale)?.[e];if(n===void 0)return e;if(t)for(let[e,r]of Object.entries(t))n=n.replace(RegExp(`\\{\\{${e}\\}\\}`,`g`),String(r));return n}get availableLocales(){return[...this.dictionaries.keys()]}};exports.Action=o,exports.CanActivate=f,exports.Component=e,exports.Email=k,exports.ErrorHandler=T,exports.FormModel=E,exports.FormSchema=N,exports.HostElement=p,exports.HttpClient=F,exports.I18nService=I,exports.Inject=c,exports.Input=n,exports.Intercept=d,exports.JunoEngine=b,exports.Match=A,exports.Param=r,exports.Pattern=j,exports.Persist=h,exports.Provide=s,exports.Refine=l,exports.Required=O,exports.RouterService=C,exports.Schema=m,exports.SchemaField=M,exports.State=t,exports.Transform=a,exports.Use=i,exports.Validate=u,exports.bootstrap=w,exports.createReactiveProxy=y,exports.s=P;
2
+ //# sourceMappingURL=index.cjs.map