@jucie.io/cli 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/jucie.js CHANGED
@@ -208,7 +208,7 @@ ${n}</style>`),e.join(`
208
208
  `):""}a(kP,"buildFontFaceBlock");function Xy(t){return t["font-family"]||t.fontFamily||null}a(Xy,"getFamily");function ip(t){return t["font-weight"]||t.fontWeight||null}a(ip,"getWeight");function cp(t){return t["font-style"]||t.fontStyle||null}a(cp,"getStyle");var vt,zt,Tr,zr,ur,up,SP,lp,$P,dp,EP,pp,NP,Tc,Qy,fp,TP,mp,zP,hp,OP,kn,Yo,gp,PP,yp,RP,zc,e_,Oc,t_,_p=class _p extends fq{constructor(){super(...arguments);j(this,up);j(this,lp);j(this,dp);j(this,pp);j(this,Tc);j(this,fp);j(this,mp);j(this,hp);j(this,kn);j(this,gp);j(this,yp);j(this,zc);j(this,Oc);j(this,vt,new Map);j(this,zt,null);j(this,Tr,null);j(this,zr,null);j(this,ur,null)}initialize(){oe(this,vt,new Map),Y(this,zc,e_).call(this)}actions(){return{resolve:(r,n,o)=>Y(this,up,SP).call(this,r,n,o),requestFont:(r,n,o)=>Y(this,gp,PP).call(this,r,n,o),hasFont:r=>Y(this,yp,RP).call(this,r),getFonts:()=>_(this,vt),buildLinks:()=>Y(this,lp,$P).call(this)}}getters(){return{contextPaths:()=>[]}}};vt=new WeakMap,zt=new WeakMap,Tr=new WeakMap,zr=new WeakMap,ur=new WeakMap,up=new WeakSet,SP=a(function(r,n="400",o="normal"){if(!r||typeof r!="string")return r;let s=za(r),i=!1;for(let{name:c,source:u,url:l}of s)u==="system"||ro(c)||Y(this,kn,Yo).call(this,c,n,o,u||"google",l)&&(i=!0);return i&&Y(this,Oc,t_).call(this),yq(r)},"#resolve"),lp=new WeakSet,$P=a(function(){return bq(Y(this,dp,EP).call(this))},"#buildLinks"),dp=new WeakSet,EP=a(function(){oe(this,vt,new Map);let r=this.inject("state");Y(this,pp,NP).call(this,r);let n=r.get(["nodes"]);return n?.app&&Y(this,Tc,Qy).call(this,"app",n,null),_(this,vt)},"#scanFonts"),pp=new WeakSet,NP=a(function(r){let n=r.get(["tokens"]);if(n){for(let[,o]of Object.entries(n))if(!(!o||o.$type!=="fontFamily"))for(let{name:s,source:i,url:c}of za(o.$value))i==="system"||ro(s)||Y(this,kn,Yo).call(this,s,"400","normal",i||"google",c)}},"#scanTokens"),Tc=new WeakSet,Qy=a(function(r,n,o){let s=n[r];if(!s)return;let{families:i}=Y(this,hp,OP).call(this,s),c=o;if(i.size>0){for(let[l,d]of i)if(d.variants.size>0)for(let p of d.variants){let[,h]=p.split(","),m=p.startsWith("1,")?"italic":"normal";Y(this,kn,Yo).call(this,l,h,m,d.source,d.url)}else Y(this,kn,Yo).call(this,l,"400","normal",d.source,d.url);c=Y(this,fp,TP).call(this,s)||[...i.keys()][0]}else if(c)for(let u of Y(this,mp,zP).call(this,s)){let l=_(this,vt).get(c),[,d]=u.split(","),p=u.startsWith("1,")?"italic":"normal";Y(this,kn,Yo).call(this,c,d,p,l?.source||"google",l?.url)}if(Array.isArray(s.children))for(let u of s.children)Y(this,Tc,Qy).call(this,u,n,c)},"#walkNode"),fp=new WeakSet,TP=a(function(r){let n=r?.style?.default;if(!n)return null;let o=Xy(n);return o&&za(o).find(i=>i.source!=="system"&&!ro(i.name))?.name||null},"#getDefaultFamily"),mp=new WeakSet,zP=a(function(r){if(!r?.style)return[];let n=new Set;for(let[,o]of Object.entries(r.style)){if(!o||typeof o!="object")continue;let s=ip(o),i=cp(o);(s||i)&&n.add(ap(s||"400",i||"normal"));for(let[c,u]of Object.entries(o))if((c.startsWith(":")||c.startsWith("&"))&&u&&typeof u=="object"){let l=ip(u),d=cp(u);(l||d)&&n.add(ap(l||"400",d||"normal"))}}return[...n]},"#extractVariantsOnly"),hp=new WeakSet,OP=a(function(r){let n=new Map;if(!r?.style)return{families:n};function o(s,i,c){if(!s)return;let u=za(s).find(l=>l.source!=="system"&&!ro(l.name));u&&(n.has(u.name)||n.set(u.name,{source:u.source||"google",url:u.url,variants:new Set}),(i||c)&&n.get(u.name).variants.add(ap(i||"400",c||"normal")))}a(o,"record");for(let[,s]of Object.entries(r.style))if(!(!s||typeof s!="object")){o(Xy(s),ip(s),cp(s));for(let[i,c]of Object.entries(s))(i.startsWith(":")||i.startsWith("&"))&&c&&typeof c=="object"&&o(Xy(c),ip(c),cp(c))}return{families:n}},"#extractNodeFonts"),kn=new WeakSet,Yo=a(function(r,n="400",o="normal",s="google",i){if(!r||ro(r))return!1;let c=ap(n,o),u=!1;_(this,vt).has(r)||(_(this,vt).set(r,{source:s||"google",url:i,variants:new Set}),u=!0,console.log("[FontResolver] registered new font:",r,"@"+s));let l=_(this,vt).get(r);return l.variants.has(c)||(l.variants.add(c),u=!0),u},"#registerFont"),gp=new WeakSet,PP=a(function(r,n="400",o="normal"){if(!r||typeof r!="string")return;let s=!1;for(let{name:i,source:c,url:u}of za(r))c==="system"||ro(i)||Y(this,kn,Yo).call(this,i,n,o,c||"google",u)&&(s=!0);s&&Y(this,Oc,t_).call(this)},"#requestFont"),yp=new WeakSet,RP=a(function(r){if(!r||typeof r!="string")return!1;let n=za(r);return n.length===0?_(this,vt).has(r):n.some(({name:o,source:s})=>s!=="system"&&!ro(o)&&_(this,vt).has(o))},"#hasFont"),zc=new WeakSet,e_=a(function(){typeof document>"u"||(_(this,zr)||(oe(this,zr,document.getElementById("jucie-fonts-preconnect-googleapis")),_(this,zr)||(oe(this,zr,document.createElement("link")),_(this,zr).id="jucie-fonts-preconnect-googleapis",_(this,zr).rel="preconnect",_(this,zr).href="https://fonts.googleapis.com",document.head.appendChild(_(this,zr)))),_(this,ur)||(oe(this,ur,document.getElementById("jucie-fonts-preconnect-gstatic")),_(this,ur)||(oe(this,ur,document.createElement("link")),_(this,ur).id="jucie-fonts-preconnect-gstatic",_(this,ur).rel="preconnect",_(this,ur).href="https://fonts.gstatic.com",_(this,ur).crossOrigin="",document.head.appendChild(_(this,ur)))),_(this,zt)||(oe(this,zt,document.getElementById("jucie-fonts")),_(this,zt)||(oe(this,zt,document.createElement("link")),_(this,zt).id="jucie-fonts",_(this,zt).rel="stylesheet",document.head.appendChild(_(this,zt)))),_(this,Tr)||(oe(this,Tr,document.getElementById("jucie-fonts-custom")),_(this,Tr)||(oe(this,Tr,document.createElement("style")),_(this,Tr).id="jucie-fonts-custom",document.head.appendChild(_(this,Tr)))))},"#ensureLinkElements"),Oc=new WeakSet,t_=a(function(){if(typeof document>"u")return;Y(this,zc,e_).call(this);let r=wP(_(this,vt));r?_(this,zt).href!==r&&(_(this,zt).href=r):_(this,zt)&&_(this,zt).removeAttribute("href");let n=kP(_(this,vt));_(this,Tr)&&(_(this,Tr).textContent=n)},"#updateFontLinks"),a(_p,"FontResolver"),Qe(_p,"manifest",{name:"FontResolver",namespace:"fontResolver"});var Nc=_p;oo();oo();oo();oo();oo();import{defineEsConfig as Uq}from"@jucie.io/engine-esbuild";import{dirname as qq,join as Vq}from"path";import{fileURLToPath as Hq}from"url";var Bq=a(()=>{let t=Hq(import.meta.url);return qq(t)},"getBundleDir"),qP=Uq("productionConfig",(t,e)=>({entryPoints:[{in:e.stageEntry||Vq(Bq(),"entry.js"),out:"main"}],bundle:!0,format:"esm",platform:"browser",sourcemap:e.sourcemap??!1,sourcesContent:!!e.sourcemap,minify:e.minify??!0,target:["es2020"],outdir:e.outdir,jsx:"automatic",jsxImportSource:e.framework==="preact"?"preact":e.framework==="vue"?"vue":"react",loader:{".js":"jsx",".ts":"ts",".tsx":"tsx",".d.ts":"ts"},define:{"process.env.NODE_ENV":JSON.stringify(process.env.NODE_ENV||"production"),"process.env.BASE_URL":JSON.stringify("/"),"process.env.JUCIE_FRAMEWORK":JSON.stringify(e.framework||"react")},treeShaking:!0,splitting:!0,chunkNames:"chunks/[name]-[hash]",assetNames:"assets/[name]-[hash]",external:["fs","path","crypto","stream","http","https","url","querystring","child_process","os","util","zlib","node:crypto","node:http","node:util","node:fs","node:path","firebase-admin","@google-cloud/*","@fastify/*","google-auth-library","google-gax","gtoken","gcp-metadata","teeny-request","jwks-rsa","agent-base","@aws-sdk/client-s3"],outExtension:{".js":".js",".css":".css"}}));import{rmSync as Yq,mkdirSync as Xq,existsSync as VP,statSync as Qq}from"fs";import{join as e3}from"path";async function HP(t={}){try{t.outdir&&VP(t.outdir)&&Yq(t.outdir,{recursive:!0,force:!0}),t.outdir&&Xq(t.outdir,{recursive:!0});let e=Jq.create().install(Wq),r=Gq.create({state:e}).install(gn.configure(t),vn.configure(t),Kq.configure({...t.esbuild??{},outdir:t.outdir,minify:t.minify??!0,sourcemap:t.sourcemap??!1,stageEntry:t.stageEntry}),Ko.configure(t),Nc.configure(t));r.esBuild.use(qP,Sn,es,$n,Xo,r_),r.cache.set(["jucieConfig"],{...t,view:"production",mode:"production"}),await r.cas.loadScene(),await r.storeParser.build();let n=r.fontResolver.buildLinks(),o=r.state.get(),s=Object.keys(o.nodes||{}).length,i=Object.keys(o.stores||{}).length;await r.esBuild.build();let c=await r.staticAssets.build({fontLinks:n});r.storeParser.stopWatching();let u="unknown";try{let l=e3(t.outdir,"main.js");VP(l)&&(u=`${(Qq(l).size/1024).toFixed(2)} KB`)}catch{}return{success:!0,outdir:t.outdir,stats:{nodeCount:s,storeCount:i,bundleSize:u,assetCount:c.assets.fileCount}}}catch(e){throw console.error(`
209
209
  \u274C Build failed:`,e),e}}a(HP,"buildForProduction");import{resolve as BP}from"path";import{pathToFileURL as o3}from"url";import{resolve as Ut,dirname as t3}from"path";function o_(t,e){if(!t)throw new Error("Config object is required");if(!t.name||typeof t.name!="string")throw new Error('Config must have a "name" field (string)');if(!t.version||typeof t.version!="string")throw new Error('Config must have a "version" field (string)');if(!t.sceneGraph||typeof t.sceneGraph!="string")throw new Error('Config must have a "sceneGraph" field (string path)');if(!t.assets||typeof t.assets!="string")throw new Error('Config must have an "assets" field (string path)');let r=e?t3(e):process.cwd(),n=t.framework??"vue",o={name:t.name,version:t.version,port:t.port??4e3,_studioUrl:t._studioUrl,sceneGraph:t.sceneGraph?Ut(r,t.sceneGraph):Ut(r,"./src/sceneGraph"),assets:t.assets?Ut(r,t.assets):Ut(r,"./src/assets"),stores:t.stores?Ut(r,t.stores):Ut(r,"./src/stores"),components:r3(t.components,r),libraries:n3(t.libraries??t.metadata?.libraries??[],r),metadata:{platform:t.metadata?.platform??n},socket:t.socket??{cors:{},options:{},auth:null},projectRoot:r,framework:n,outdir:Ut(r,t.dist||"dist"),esbuild:t.esbuild??{}};if(typeof o.port!="number"||o.port<1||o.port>65535)throw new Error('Config "port" must be a number between 1 and 65535');if(typeof o.metadata.platform!="string")throw new Error('Config "metadata.platform" must be a string');if(!Array.isArray(o.libraries))throw new Error('Config "libraries" must be an array');return o}a(o_,"defineConfig");function r3(t,e){let r=Ut(e,"./src/components");return t?typeof t=="string"?Ut(e,t):Array.isArray(t)?t.map(n=>{if(typeof n=="string")return Ut(e,n);if(n&&typeof n=="object"&&n.name&&n.from){let o=n.from.startsWith(".")?Ut(e,n.from):n.from,s=n.manifest?n.manifest.startsWith(".")?Ut(e,n.manifest):n.manifest:null;return{...n,from:o,manifest:s}}return n}):r:r}a(r3,"resolveComponents");function n3(t,e){return Array.isArray(t)?t.map(r=>{if(typeof r=="string")return r;if(r&&typeof r=="object"&&r.path){let n=r.path.startsWith(".")?Ut(e,r.path):r.path;return{...r,path:n}}return r}):[]}a(n3,"resolveLibraries");async function ts(t){let e;t?e=BP(process.cwd(),t):e=BP(process.cwd(),"jucie.config.js");try{let o=(await import(o3(e).href)).default;if(!o)throw new Error("Config file must export a default object");return o_(o,e)}catch(r){throw r.code==="ERR_MODULE_NOT_FOUND"||r.code==="ENOENT"?new Error(`Config file not found: ${e}`):r.message.includes("Config must")||r.message.includes('Config "')?r:new Error(`Failed to load config: ${r.message}`)}}a(ts,"loadConfig");async function s_(t={},e={}){try{console.log(`
210
210
  \u{1F528} Building Jucie project for production...
211
- `);let r=t.config||process.env.JUCIE_CONFIG||"jucie.config.js",n=await ts(r),o=t.outdir||t.o,s=o?WP(o)?o:GP(process.cwd(),o):n.outdir,i=t.htmlTemplate,c=i?WP(i)?i:GP(process.cwd(),i):JP(n.projectRoot,"index.html"),u=s3(i3(import.meta.url)),l=JP(u,"stage-src","production","entry.js"),d={...n,outdir:s,stageEntry:a3(l)?l:void 0,minify:t.minify??!0,sourcemap:t.sourcemap??!1,analyze:t.analyze??!1,branch:t.branch||t.b||"main",htmlTemplate:c,view:"production",mode:"production"};e.verbose&&(console.log("Build configuration:",d),console.log(""));let p=await HP(d);return p.success&&(console.log(`
211
+ `);let r=t.config||process.env.JUCIE_CONFIG||"jucie.config.js",n=await ts(r),o=t.outdir||t.o,s=o?WP(o)?o:GP(process.cwd(),o):n.outdir,i=t.htmlTemplate,c=i?WP(i)?i:GP(process.cwd(),i):JP(n.projectRoot,"index.html"),u=s3(i3(import.meta.url)),l=JP(u,"stage","prod.js"),d={...n,outdir:s,stageEntry:a3(l)?l:void 0,minify:t.minify??!0,sourcemap:t.sourcemap??!1,analyze:t.analyze??!1,branch:t.branch||t.b||"main",htmlTemplate:c,view:"production",mode:"production"};e.verbose&&(console.log("Build configuration:",d),console.log(""));let p=await HP(d);return p.success&&(console.log(`
212
212
  \u2705 Build complete!
213
213
  `),console.log(`\u{1F4E6} Output directory: ${p.outdir}`),console.log(`\u{1F4CA} Bundle size: ${p.stats.bundleSize}`),console.log(`\u{1F3AF} Nodes compiled: ${p.stats.nodeCount}`),console.log(`\u{1F4C1} Stores: ${p.stats.storeCount}`),console.log(`\u{1F5BC}\uFE0F Assets copied: ${p.stats.assetCount}`),console.log(`
214
214
  \u{1F4A1} Deploy the dist/ folder to your hosting provider
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jucie.io/cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "CLI tool for creating and managing Jucie projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -55,7 +55,11 @@
55
55
  "bugs": {
56
56
  "url": "https://github.com/adrianjonmiller/jucie/issues"
57
57
  },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ },
58
61
  "dependencies": {
62
+ "@babel/parser": "^7.29.0",
59
63
  "@jucie.io/engine": "^1.1.77",
60
64
  "@jucie.io/engine-esbuild": "^1.0.16",
61
65
  "@jucie.io/engine-message": "^1.0.35",
@@ -67,7 +71,11 @@
67
71
  "@jucie.io/state-history": "^1.0.20",
68
72
  "@jucie.io/state-matcher": "^1.0.18",
69
73
  "@jucie.io/state-on-change": "^1.0.18",
70
- "esbuild": "^0.20.0"
74
+ "chokidar": "^3.6.0",
75
+ "esbuild": "^0.20.0",
76
+ "glob": "^13.0.0",
77
+ "image-size": "^1.2.0",
78
+ "recast": "^0.23.0"
71
79
  },
72
80
  "devDependencies": {
73
81
  "@brickworks/result": "^2.0.2",
@@ -1,38 +0,0 @@
1
- // Engine
2
- import { Engine } from '@jucie.io/engine';
3
-
4
- // Engine Extensions
5
- import { SceneCompiler } from '@packages/engine-scene-compiler';
6
- import { PROTOTYPES } from '@packages/scene-graph/nodes/prototypes/main.js';
7
-
8
- // State Extensions
9
- import { State } from '@jucie.io/state';
10
- import { JucieState } from '@jucie.io/reactive-jucie-state';
11
-
12
- // Utils
13
- import { initializeNode } from '@packages/stage/lib/utils/initializeNode.js';
14
-
15
- export const createProductionBootstrap = ({ config = {} } = {}) => new Promise(async (resolve, reject) => {
16
- try {
17
- const { loadProjectMain } = await import('jucie:sdk');
18
- await loadProjectMain();
19
- const { scene } = await import('jucie:scene');
20
- const sources = (await import('@components'))?.default ?? {};
21
-
22
- // Ensure mount point exists (index.html already has #app; this is a safety net)
23
- initializeNode(config.$el || 'app');
24
-
25
- const state = State.create(scene).install(JucieState);
26
- const engine = Engine.create({ state }).install(
27
- SceneCompiler.configure({ ...config, view: config.view || 'production' })
28
- );
29
-
30
- engine.sceneCompiler.loadPrototypes(PROTOTYPES);
31
- engine.sceneCompiler.loadSources(sources);
32
- await engine.sceneCompiler.create('app');
33
-
34
- resolve(config)
35
- } catch (error) {
36
- reject(error)
37
- }
38
- })
@@ -1,51 +0,0 @@
1
- import { defineEsConfig } from '@jucie.io/engine-esbuild';
2
- import { dirname, join } from 'path';
3
- import { fileURLToPath } from 'url';
4
-
5
- const getBundleDir = () => {
6
- const filename = fileURLToPath(import.meta.url);
7
- return dirname(filename);
8
- };
9
-
10
- export const productionConfig = defineEsConfig('productionConfig', (_, config) => ({
11
- entryPoints: [{ in: config.stageEntry || join(getBundleDir(), 'entry.js'), out: 'main' }],
12
- bundle: true,
13
- format: 'esm',
14
- platform: 'browser',
15
- sourcemap: config.sourcemap ?? false,
16
- sourcesContent: !!config.sourcemap,
17
- minify: config.minify ?? true,
18
- target: ['es2020'],
19
- outdir: config.outdir,
20
- jsx: 'automatic',
21
- jsxImportSource: config.framework === 'preact' ? 'preact'
22
- : config.framework === 'vue' ? 'vue'
23
- : 'react',
24
- loader: {
25
- '.js': 'jsx',
26
- '.ts': 'ts',
27
- '.tsx': 'tsx',
28
- '.d.ts': 'ts'
29
- },
30
- define: {
31
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
32
- 'process.env.BASE_URL': JSON.stringify('/'),
33
- 'process.env.JUCIE_FRAMEWORK': JSON.stringify(config.framework || 'react'),
34
- },
35
- treeShaking: true,
36
- splitting: true,
37
- chunkNames: 'chunks/[name]-[hash]',
38
- assetNames: 'assets/[name]-[hash]',
39
- external: [
40
- 'fs', 'path', 'crypto', 'stream', 'http', 'https', 'url',
41
- 'querystring', 'child_process', 'os', 'util', 'zlib', 'node:crypto',
42
- 'node:http', 'node:util', 'node:fs', 'node:path',
43
- 'firebase-admin', '@google-cloud/*', '@fastify/*',
44
- 'google-auth-library', 'google-gax', 'gtoken', 'gcp-metadata',
45
- 'teeny-request', 'jwks-rsa', 'agent-base', '@aws-sdk/client-s3'
46
- ],
47
- outExtension: {
48
- '.js': '.js',
49
- '.css': '.css'
50
- }
51
- }))
@@ -1,4 +0,0 @@
1
- import { jucieConfig } from 'jucie:config';
2
- import { createProductionBootstrap } from './bootstrap.js';
3
-
4
- createProductionBootstrap({ config: jucieConfig });