@al8b/runtime 0.1.13 → 0.1.14
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/assets/index.d.mts +0 -1
- package/dist/assets/index.d.ts +0 -1
- package/dist/assets/loader.d.mts +0 -1
- package/dist/assets/loader.d.ts +0 -1
- package/dist/browser/index.js +780 -2681
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.min.js +27 -39
- package/dist/core/api-factory.d.mts +1 -5
- package/dist/core/api-factory.d.ts +1 -5
- package/dist/core/api-factory.js +17 -38
- package/dist/core/api-factory.js.map +1 -1
- package/dist/core/api-factory.mjs +18 -38
- package/dist/core/api-factory.mjs.map +1 -1
- package/dist/core/controller.d.mts +0 -5
- package/dist/core/controller.d.ts +0 -5
- package/dist/core/controller.js +23 -98
- package/dist/core/controller.js.map +1 -1
- package/dist/core/controller.mjs +24 -99
- package/dist/core/controller.mjs.map +1 -1
- package/dist/core/debug-logger.d.mts +0 -1
- package/dist/core/debug-logger.d.ts +0 -1
- package/dist/core/error-handler.d.mts +1 -2
- package/dist/core/error-handler.d.ts +1 -2
- package/dist/core/error-handler.js +2 -17
- package/dist/core/error-handler.js.map +1 -1
- package/dist/core/error-handler.mjs +2 -17
- package/dist/core/error-handler.mjs.map +1 -1
- package/dist/core/index.d.mts +0 -2
- package/dist/core/index.d.ts +0 -2
- package/dist/core/index.js +23 -98
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +24 -99
- package/dist/core/index.mjs.map +1 -1
- package/dist/hot-reload/index.d.mts +0 -1
- package/dist/hot-reload/index.d.ts +0 -1
- package/dist/hot-reload/index.js.map +1 -1
- package/dist/hot-reload/index.mjs.map +1 -1
- package/dist/hot-reload/updater.d.mts +0 -1
- package/dist/hot-reload/updater.d.ts +0 -1
- package/dist/hot-reload/updater.js.map +1 -1
- package/dist/hot-reload/updater.mjs.map +1 -1
- package/dist/index.d.mts +0 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.js +23 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -99
- package/dist/index.mjs.map +1 -1
- package/dist/types/bridge.d.mts +0 -4
- package/dist/types/bridge.d.ts +0 -4
- package/dist/types/bridge.js.map +1 -1
- package/dist/types/index.d.mts +0 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/runtime.d.mts +13 -2
- package/dist/types/runtime.d.ts +13 -2
- package/dist/types/runtime.js.map +1 -1
- package/package.json +12 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hot-reload/updater.ts"],"sourcesContent":["/**\n * Source code updater for hot reload\n * Matches runtime behavior for source updates\n */\n\nimport type { L8BVM } from \"@al8b/vm\";\nimport type { RuntimeListener } from \"../types\";\n\nexport class SourceUpdater {\n\tprivate updateMemory: Record<string, string> = {};\n\tprivate previousInit: string | null = null;\n\n\tconstructor(\n\t\tprivate vm: L8BVM,\n\t\tprivate listener: RuntimeListener,\n\t\tprivate audio?: { cancelBeeps(): void },\n\t\tprivate screen?: { clear(): void },\n\t\tprivate reportWarnings?: () => void,\n\t\tprivate emitBridgeEvent?: (name: string, payload?: unknown) => void,\n\t) {}\n\n\t/**\n\t * Update source code (hot reload)\n\t */\n\tupdateSource(file: string, src: string, reinit = false): boolean {\n\t\t// Return false if VM is not available\n\t\tif (!this.vm) return false;\n\n\t\t// Return false if source code hasn't changed\n\t\tif (src === this.updateMemory[file]) return false;\n\n\t\tthis.updateMemory[file] = src;\n\n\t\t// Cancel beeps and clear screen before hot reload\n\t\tif (this.audio) {\n\t\t\tthis.audio.cancelBeeps();\n\t\t}\n\t\tif (this.screen) {\n\t\t\tthis.screen.clear();\n\t\t}\n\n\t\ttry {\n\t\t\t// Compile and execute updated source code\n\t\t\t// Timeout of 3000ms prevents infinite loops during hot reload\n\t\t\tthis.vm.run(src, 3000, file);\n\n\t\t\t// Notify parent process of successful compilation\n\t\t\tif (this.emitBridgeEvent) {\n\t\t\t\tthis.emitBridgeEvent(\"compile_success\", { file });\n\t\t\t}\n\n\t\t\t// Report warnings after compilation\n\t\t\tif (this.reportWarnings) {\n\t\t\t\tthis.reportWarnings();\n\t\t\t}\n\n\t\t\t// Check for compilation or runtime errors from VM\n\t\t\tif (this.vm.error_info) {\n\t\t\t\tconst err: any = Object.assign({}, this.vm.error_info);\n\t\t\t\terr.type = \"init\";\n\t\t\t\terr.file = file;\n\t\t\t\tthis.listener.reportError?.(err);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Re-run init() function if it was modified during hot reload\n\t\t\t// This allows reinitialization without full page refresh\n\t\t\tif (
|
|
1
|
+
{"version":3,"sources":["../../src/hot-reload/updater.ts"],"sourcesContent":["/**\n * Source code updater for hot reload\n * Matches runtime behavior for source updates\n */\n\nimport type { L8BVM } from \"@al8b/vm\";\nimport type { RuntimeListener } from \"../types\";\n\nexport class SourceUpdater {\n\tprivate updateMemory: Record<string, string> = {};\n\tprivate previousInit: string | null = null;\n\n\tconstructor(\n\t\tprivate vm: L8BVM,\n\t\tprivate listener: RuntimeListener,\n\t\tprivate audio?: { cancelBeeps(): void },\n\t\tprivate screen?: { clear(): void },\n\t\tprivate reportWarnings?: () => void,\n\t\tprivate emitBridgeEvent?: (name: string, payload?: unknown) => void,\n\t) {}\n\n\t/**\n\t * Update source code (hot reload)\n\t */\n\tupdateSource(file: string, src: string, reinit = false): boolean {\n\t\t// Return false if VM is not available\n\t\tif (!this.vm) return false;\n\n\t\t// Return false if source code hasn't changed\n\t\tif (src === this.updateMemory[file]) return false;\n\n\t\tthis.updateMemory[file] = src;\n\n\t\t// Cancel beeps and clear screen before hot reload\n\t\tif (this.audio) {\n\t\t\tthis.audio.cancelBeeps();\n\t\t}\n\t\tif (this.screen) {\n\t\t\tthis.screen.clear();\n\t\t}\n\n\t\ttry {\n\t\t\t// Compile and execute updated source code\n\t\t\t// Timeout of 3000ms prevents infinite loops during hot reload\n\t\t\tthis.vm.run(src, 3000, file);\n\n\t\t\t// Notify parent process of successful compilation\n\t\t\tif (this.emitBridgeEvent) {\n\t\t\t\tthis.emitBridgeEvent(\"compile_success\", { file });\n\t\t\t}\n\n\t\t\t// Report warnings after compilation\n\t\t\tif (this.reportWarnings) {\n\t\t\t\tthis.reportWarnings();\n\t\t\t}\n\n\t\t\t// Check for compilation or runtime errors from VM\n\t\t\tif (this.vm.error_info) {\n\t\t\t\tconst err: any = Object.assign({}, this.vm.error_info);\n\t\t\t\terr.type = \"init\";\n\t\t\t\terr.file = file;\n\t\t\t\tthis.listener.reportError?.(err);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Re-run init() function if it was modified during hot reload\n\t\t\t// This allows reinitialization without full page refresh\n\t\t\tif (this.vm.runner?.getFunctionSource) {\n\t\t\t\tconst init = this.vm.runner.getFunctionSource(\"init\");\n\t\t\t\tif (init && init !== this.previousInit && reinit) {\n\t\t\t\t\tthis.previousInit = init;\n\t\t\t\t\tthis.vm.call(\"init\");\n\t\t\t\t\tif (this.vm.error_info) {\n\t\t\t\t\t\tconst err: any = Object.assign({}, this.vm.error_info);\n\t\t\t\t\t\terr.type = \"init\";\n\t\t\t\t\t\tthis.listener.reportError?.(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (err: any) {\n\t\t\t// Handle exceptions during compilation or execution\n\t\t\terr.file = file;\n\t\t\tthis.listener.reportError?.(err);\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"],"mappings":";;;;AAQO,IAAMA,gBAAN,MAAMA;EARb,OAQaA;;;;;;;;;EACJC,eAAuC,CAAC;EACxCC,eAA8B;EAEtC,YACSC,IACAC,UACAC,OACAC,QACAC,gBACAC,iBACP;SANOL,KAAAA;SACAC,WAAAA;SACAC,QAAAA;SACAC,SAAAA;SACAC,iBAAAA;SACAC,kBAAAA;EACN;;;;EAKHC,aAAaC,MAAcC,KAAaC,SAAS,OAAgB;AAEhE,QAAI,CAAC,KAAKT,GAAI,QAAO;AAGrB,QAAIQ,QAAQ,KAAKV,aAAaS,IAAAA,EAAO,QAAO;AAE5C,SAAKT,aAAaS,IAAAA,IAAQC;AAG1B,QAAI,KAAKN,OAAO;AACf,WAAKA,MAAMQ,YAAW;IACvB;AACA,QAAI,KAAKP,QAAQ;AAChB,WAAKA,OAAOQ,MAAK;IAClB;AAEA,QAAI;AAGH,WAAKX,GAAGY,IAAIJ,KAAK,KAAMD,IAAAA;AAGvB,UAAI,KAAKF,iBAAiB;AACzB,aAAKA,gBAAgB,mBAAmB;UAAEE;QAAK,CAAA;MAChD;AAGA,UAAI,KAAKH,gBAAgB;AACxB,aAAKA,eAAc;MACpB;AAGA,UAAI,KAAKJ,GAAGa,YAAY;AACvB,cAAMC,MAAWC,OAAOC,OAAO,CAAC,GAAG,KAAKhB,GAAGa,UAAU;AACrDC,YAAIG,OAAO;AACXH,YAAIP,OAAOA;AACX,aAAKN,SAASiB,cAAcJ,GAAAA;AAC5B,eAAO;MACR;AAIA,UAAI,KAAKd,GAAGmB,QAAQC,mBAAmB;AACtC,cAAMC,OAAO,KAAKrB,GAAGmB,OAAOC,kBAAkB,MAAA;AAC9C,YAAIC,QAAQA,SAAS,KAAKtB,gBAAgBU,QAAQ;AACjD,eAAKV,eAAesB;AACpB,eAAKrB,GAAGsB,KAAK,MAAA;AACb,cAAI,KAAKtB,GAAGa,YAAY;AACvB,kBAAMC,MAAWC,OAAOC,OAAO,CAAC,GAAG,KAAKhB,GAAGa,UAAU;AACrDC,gBAAIG,OAAO;AACX,iBAAKhB,SAASiB,cAAcJ,GAAAA;UAC7B;QACD;MACD;AAEA,aAAO;IACR,SAASA,KAAU;AAElBA,UAAIP,OAAOA;AACX,WAAKN,SAASiB,cAAcJ,GAAAA;AAC5B,aAAO;IACR;EACD;AACD;","names":["SourceUpdater","updateMemory","previousInit","vm","listener","audio","screen","reportWarnings","emitBridgeEvent","updateSource","file","src","reinit","cancelBeeps","clear","run","error_info","err","Object","assign","type","reportError","runner","getFunctionSource","init","call"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hot-reload/updater.ts"],"sourcesContent":["/**\n * Source code updater for hot reload\n * Matches runtime behavior for source updates\n */\n\nimport type { L8BVM } from \"@al8b/vm\";\nimport type { RuntimeListener } from \"../types\";\n\nexport class SourceUpdater {\n\tprivate updateMemory: Record<string, string> = {};\n\tprivate previousInit: string | null = null;\n\n\tconstructor(\n\t\tprivate vm: L8BVM,\n\t\tprivate listener: RuntimeListener,\n\t\tprivate audio?: { cancelBeeps(): void },\n\t\tprivate screen?: { clear(): void },\n\t\tprivate reportWarnings?: () => void,\n\t\tprivate emitBridgeEvent?: (name: string, payload?: unknown) => void,\n\t) {}\n\n\t/**\n\t * Update source code (hot reload)\n\t */\n\tupdateSource(file: string, src: string, reinit = false): boolean {\n\t\t// Return false if VM is not available\n\t\tif (!this.vm) return false;\n\n\t\t// Return false if source code hasn't changed\n\t\tif (src === this.updateMemory[file]) return false;\n\n\t\tthis.updateMemory[file] = src;\n\n\t\t// Cancel beeps and clear screen before hot reload\n\t\tif (this.audio) {\n\t\t\tthis.audio.cancelBeeps();\n\t\t}\n\t\tif (this.screen) {\n\t\t\tthis.screen.clear();\n\t\t}\n\n\t\ttry {\n\t\t\t// Compile and execute updated source code\n\t\t\t// Timeout of 3000ms prevents infinite loops during hot reload\n\t\t\tthis.vm.run(src, 3000, file);\n\n\t\t\t// Notify parent process of successful compilation\n\t\t\tif (this.emitBridgeEvent) {\n\t\t\t\tthis.emitBridgeEvent(\"compile_success\", { file });\n\t\t\t}\n\n\t\t\t// Report warnings after compilation\n\t\t\tif (this.reportWarnings) {\n\t\t\t\tthis.reportWarnings();\n\t\t\t}\n\n\t\t\t// Check for compilation or runtime errors from VM\n\t\t\tif (this.vm.error_info) {\n\t\t\t\tconst err: any = Object.assign({}, this.vm.error_info);\n\t\t\t\terr.type = \"init\";\n\t\t\t\terr.file = file;\n\t\t\t\tthis.listener.reportError?.(err);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Re-run init() function if it was modified during hot reload\n\t\t\t// This allows reinitialization without full page refresh\n\t\t\tif (
|
|
1
|
+
{"version":3,"sources":["../../src/hot-reload/updater.ts"],"sourcesContent":["/**\n * Source code updater for hot reload\n * Matches runtime behavior for source updates\n */\n\nimport type { L8BVM } from \"@al8b/vm\";\nimport type { RuntimeListener } from \"../types\";\n\nexport class SourceUpdater {\n\tprivate updateMemory: Record<string, string> = {};\n\tprivate previousInit: string | null = null;\n\n\tconstructor(\n\t\tprivate vm: L8BVM,\n\t\tprivate listener: RuntimeListener,\n\t\tprivate audio?: { cancelBeeps(): void },\n\t\tprivate screen?: { clear(): void },\n\t\tprivate reportWarnings?: () => void,\n\t\tprivate emitBridgeEvent?: (name: string, payload?: unknown) => void,\n\t) {}\n\n\t/**\n\t * Update source code (hot reload)\n\t */\n\tupdateSource(file: string, src: string, reinit = false): boolean {\n\t\t// Return false if VM is not available\n\t\tif (!this.vm) return false;\n\n\t\t// Return false if source code hasn't changed\n\t\tif (src === this.updateMemory[file]) return false;\n\n\t\tthis.updateMemory[file] = src;\n\n\t\t// Cancel beeps and clear screen before hot reload\n\t\tif (this.audio) {\n\t\t\tthis.audio.cancelBeeps();\n\t\t}\n\t\tif (this.screen) {\n\t\t\tthis.screen.clear();\n\t\t}\n\n\t\ttry {\n\t\t\t// Compile and execute updated source code\n\t\t\t// Timeout of 3000ms prevents infinite loops during hot reload\n\t\t\tthis.vm.run(src, 3000, file);\n\n\t\t\t// Notify parent process of successful compilation\n\t\t\tif (this.emitBridgeEvent) {\n\t\t\t\tthis.emitBridgeEvent(\"compile_success\", { file });\n\t\t\t}\n\n\t\t\t// Report warnings after compilation\n\t\t\tif (this.reportWarnings) {\n\t\t\t\tthis.reportWarnings();\n\t\t\t}\n\n\t\t\t// Check for compilation or runtime errors from VM\n\t\t\tif (this.vm.error_info) {\n\t\t\t\tconst err: any = Object.assign({}, this.vm.error_info);\n\t\t\t\terr.type = \"init\";\n\t\t\t\terr.file = file;\n\t\t\t\tthis.listener.reportError?.(err);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Re-run init() function if it was modified during hot reload\n\t\t\t// This allows reinitialization without full page refresh\n\t\t\tif (this.vm.runner?.getFunctionSource) {\n\t\t\t\tconst init = this.vm.runner.getFunctionSource(\"init\");\n\t\t\t\tif (init && init !== this.previousInit && reinit) {\n\t\t\t\t\tthis.previousInit = init;\n\t\t\t\t\tthis.vm.call(\"init\");\n\t\t\t\t\tif (this.vm.error_info) {\n\t\t\t\t\t\tconst err: any = Object.assign({}, this.vm.error_info);\n\t\t\t\t\t\terr.type = \"init\";\n\t\t\t\t\t\tthis.listener.reportError?.(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (err: any) {\n\t\t\t// Handle exceptions during compilation or execution\n\t\t\terr.file = file;\n\t\t\tthis.listener.reportError?.(err);\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAQO,IAAMA,gBAAN,MAAMA;EARb,OAQaA;;;;;;;;;EACJC,eAAuC,CAAC;EACxCC,eAA8B;EAEtC,YACSC,IACAC,UACAC,OACAC,QACAC,gBACAC,iBACP;SANOL,KAAAA;SACAC,WAAAA;SACAC,QAAAA;SACAC,SAAAA;SACAC,iBAAAA;SACAC,kBAAAA;EACN;;;;EAKHC,aAAaC,MAAcC,KAAaC,SAAS,OAAgB;AAEhE,QAAI,CAAC,KAAKT,GAAI,QAAO;AAGrB,QAAIQ,QAAQ,KAAKV,aAAaS,IAAAA,EAAO,QAAO;AAE5C,SAAKT,aAAaS,IAAAA,IAAQC;AAG1B,QAAI,KAAKN,OAAO;AACf,WAAKA,MAAMQ,YAAW;IACvB;AACA,QAAI,KAAKP,QAAQ;AAChB,WAAKA,OAAOQ,MAAK;IAClB;AAEA,QAAI;AAGH,WAAKX,GAAGY,IAAIJ,KAAK,KAAMD,IAAAA;AAGvB,UAAI,KAAKF,iBAAiB;AACzB,aAAKA,gBAAgB,mBAAmB;UAAEE;QAAK,CAAA;MAChD;AAGA,UAAI,KAAKH,gBAAgB;AACxB,aAAKA,eAAc;MACpB;AAGA,UAAI,KAAKJ,GAAGa,YAAY;AACvB,cAAMC,MAAWC,OAAOC,OAAO,CAAC,GAAG,KAAKhB,GAAGa,UAAU;AACrDC,YAAIG,OAAO;AACXH,YAAIP,OAAOA;AACX,aAAKN,SAASiB,cAAcJ,GAAAA;AAC5B,eAAO;MACR;AAIA,UAAI,KAAKd,GAAGmB,QAAQC,mBAAmB;AACtC,cAAMC,OAAO,KAAKrB,GAAGmB,OAAOC,kBAAkB,MAAA;AAC9C,YAAIC,QAAQA,SAAS,KAAKtB,gBAAgBU,QAAQ;AACjD,eAAKV,eAAesB;AACpB,eAAKrB,GAAGsB,KAAK,MAAA;AACb,cAAI,KAAKtB,GAAGa,YAAY;AACvB,kBAAMC,MAAWC,OAAOC,OAAO,CAAC,GAAG,KAAKhB,GAAGa,UAAU;AACrDC,gBAAIG,OAAO;AACX,iBAAKhB,SAASiB,cAAcJ,GAAAA;UAC7B;QACD;MACD;AAEA,aAAO;IACR,SAASA,KAAU;AAElBA,UAAIP,OAAOA;AACX,WAAKN,SAASiB,cAAcJ,GAAAA;AAC5B,aAAO;IACR;EACD;AACD;","names":["SourceUpdater","updateMemory","previousInit","vm","listener","audio","screen","reportWarnings","emitBridgeEvent","updateSource","file","src","reinit","cancelBeeps","clear","run","error_info","err","Object","assign","type","reportError","runner","getFunctionSource","init","call"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hot-reload/updater.ts"],"sourcesContent":["/**\n * Source code updater for hot reload\n * Matches runtime behavior for source updates\n */\n\nimport type { L8BVM } from \"@al8b/vm\";\nimport type { RuntimeListener } from \"../types\";\n\nexport class SourceUpdater {\n\tprivate updateMemory: Record<string, string> = {};\n\tprivate previousInit: string | null = null;\n\n\tconstructor(\n\t\tprivate vm: L8BVM,\n\t\tprivate listener: RuntimeListener,\n\t\tprivate audio?: { cancelBeeps(): void },\n\t\tprivate screen?: { clear(): void },\n\t\tprivate reportWarnings?: () => void,\n\t\tprivate emitBridgeEvent?: (name: string, payload?: unknown) => void,\n\t) {}\n\n\t/**\n\t * Update source code (hot reload)\n\t */\n\tupdateSource(file: string, src: string, reinit = false): boolean {\n\t\t// Return false if VM is not available\n\t\tif (!this.vm) return false;\n\n\t\t// Return false if source code hasn't changed\n\t\tif (src === this.updateMemory[file]) return false;\n\n\t\tthis.updateMemory[file] = src;\n\n\t\t// Cancel beeps and clear screen before hot reload\n\t\tif (this.audio) {\n\t\t\tthis.audio.cancelBeeps();\n\t\t}\n\t\tif (this.screen) {\n\t\t\tthis.screen.clear();\n\t\t}\n\n\t\ttry {\n\t\t\t// Compile and execute updated source code\n\t\t\t// Timeout of 3000ms prevents infinite loops during hot reload\n\t\t\tthis.vm.run(src, 3000, file);\n\n\t\t\t// Notify parent process of successful compilation\n\t\t\tif (this.emitBridgeEvent) {\n\t\t\t\tthis.emitBridgeEvent(\"compile_success\", { file });\n\t\t\t}\n\n\t\t\t// Report warnings after compilation\n\t\t\tif (this.reportWarnings) {\n\t\t\t\tthis.reportWarnings();\n\t\t\t}\n\n\t\t\t// Check for compilation or runtime errors from VM\n\t\t\tif (this.vm.error_info) {\n\t\t\t\tconst err: any = Object.assign({}, this.vm.error_info);\n\t\t\t\terr.type = \"init\";\n\t\t\t\terr.file = file;\n\t\t\t\tthis.listener.reportError?.(err);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Re-run init() function if it was modified during hot reload\n\t\t\t// This allows reinitialization without full page refresh\n\t\t\tif (
|
|
1
|
+
{"version":3,"sources":["../../src/hot-reload/updater.ts"],"sourcesContent":["/**\n * Source code updater for hot reload\n * Matches runtime behavior for source updates\n */\n\nimport type { L8BVM } from \"@al8b/vm\";\nimport type { RuntimeListener } from \"../types\";\n\nexport class SourceUpdater {\n\tprivate updateMemory: Record<string, string> = {};\n\tprivate previousInit: string | null = null;\n\n\tconstructor(\n\t\tprivate vm: L8BVM,\n\t\tprivate listener: RuntimeListener,\n\t\tprivate audio?: { cancelBeeps(): void },\n\t\tprivate screen?: { clear(): void },\n\t\tprivate reportWarnings?: () => void,\n\t\tprivate emitBridgeEvent?: (name: string, payload?: unknown) => void,\n\t) {}\n\n\t/**\n\t * Update source code (hot reload)\n\t */\n\tupdateSource(file: string, src: string, reinit = false): boolean {\n\t\t// Return false if VM is not available\n\t\tif (!this.vm) return false;\n\n\t\t// Return false if source code hasn't changed\n\t\tif (src === this.updateMemory[file]) return false;\n\n\t\tthis.updateMemory[file] = src;\n\n\t\t// Cancel beeps and clear screen before hot reload\n\t\tif (this.audio) {\n\t\t\tthis.audio.cancelBeeps();\n\t\t}\n\t\tif (this.screen) {\n\t\t\tthis.screen.clear();\n\t\t}\n\n\t\ttry {\n\t\t\t// Compile and execute updated source code\n\t\t\t// Timeout of 3000ms prevents infinite loops during hot reload\n\t\t\tthis.vm.run(src, 3000, file);\n\n\t\t\t// Notify parent process of successful compilation\n\t\t\tif (this.emitBridgeEvent) {\n\t\t\t\tthis.emitBridgeEvent(\"compile_success\", { file });\n\t\t\t}\n\n\t\t\t// Report warnings after compilation\n\t\t\tif (this.reportWarnings) {\n\t\t\t\tthis.reportWarnings();\n\t\t\t}\n\n\t\t\t// Check for compilation or runtime errors from VM\n\t\t\tif (this.vm.error_info) {\n\t\t\t\tconst err: any = Object.assign({}, this.vm.error_info);\n\t\t\t\terr.type = \"init\";\n\t\t\t\terr.file = file;\n\t\t\t\tthis.listener.reportError?.(err);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Re-run init() function if it was modified during hot reload\n\t\t\t// This allows reinitialization without full page refresh\n\t\t\tif (this.vm.runner?.getFunctionSource) {\n\t\t\t\tconst init = this.vm.runner.getFunctionSource(\"init\");\n\t\t\t\tif (init && init !== this.previousInit && reinit) {\n\t\t\t\t\tthis.previousInit = init;\n\t\t\t\t\tthis.vm.call(\"init\");\n\t\t\t\t\tif (this.vm.error_info) {\n\t\t\t\t\t\tconst err: any = Object.assign({}, this.vm.error_info);\n\t\t\t\t\t\terr.type = \"init\";\n\t\t\t\t\t\tthis.listener.reportError?.(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (err: any) {\n\t\t\t// Handle exceptions during compilation or execution\n\t\t\terr.file = file;\n\t\t\tthis.listener.reportError?.(err);\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"],"mappings":";;;;AAQO,IAAMA,gBAAN,MAAMA;EARb,OAQaA;;;;;;;;;EACJC,eAAuC,CAAC;EACxCC,eAA8B;EAEtC,YACSC,IACAC,UACAC,OACAC,QACAC,gBACAC,iBACP;SANOL,KAAAA;SACAC,WAAAA;SACAC,QAAAA;SACAC,SAAAA;SACAC,iBAAAA;SACAC,kBAAAA;EACN;;;;EAKHC,aAAaC,MAAcC,KAAaC,SAAS,OAAgB;AAEhE,QAAI,CAAC,KAAKT,GAAI,QAAO;AAGrB,QAAIQ,QAAQ,KAAKV,aAAaS,IAAAA,EAAO,QAAO;AAE5C,SAAKT,aAAaS,IAAAA,IAAQC;AAG1B,QAAI,KAAKN,OAAO;AACf,WAAKA,MAAMQ,YAAW;IACvB;AACA,QAAI,KAAKP,QAAQ;AAChB,WAAKA,OAAOQ,MAAK;IAClB;AAEA,QAAI;AAGH,WAAKX,GAAGY,IAAIJ,KAAK,KAAMD,IAAAA;AAGvB,UAAI,KAAKF,iBAAiB;AACzB,aAAKA,gBAAgB,mBAAmB;UAAEE;QAAK,CAAA;MAChD;AAGA,UAAI,KAAKH,gBAAgB;AACxB,aAAKA,eAAc;MACpB;AAGA,UAAI,KAAKJ,GAAGa,YAAY;AACvB,cAAMC,MAAWC,OAAOC,OAAO,CAAC,GAAG,KAAKhB,GAAGa,UAAU;AACrDC,YAAIG,OAAO;AACXH,YAAIP,OAAOA;AACX,aAAKN,SAASiB,cAAcJ,GAAAA;AAC5B,eAAO;MACR;AAIA,UAAI,KAAKd,GAAGmB,QAAQC,mBAAmB;AACtC,cAAMC,OAAO,KAAKrB,GAAGmB,OAAOC,kBAAkB,MAAA;AAC9C,YAAIC,QAAQA,SAAS,KAAKtB,gBAAgBU,QAAQ;AACjD,eAAKV,eAAesB;AACpB,eAAKrB,GAAGsB,KAAK,MAAA;AACb,cAAI,KAAKtB,GAAGa,YAAY;AACvB,kBAAMC,MAAWC,OAAOC,OAAO,CAAC,GAAG,KAAKhB,GAAGa,UAAU;AACrDC,gBAAIG,OAAO;AACX,iBAAKhB,SAASiB,cAAcJ,GAAAA;UAC7B;QACD;MACD;AAEA,aAAO;IACR,SAASA,KAAU;AAElBA,UAAIP,OAAOA;AACX,WAAKN,SAASiB,cAAcJ,GAAAA;AAC5B,aAAO;IACR;EACD;AACD;","names":["SourceUpdater","updateMemory","previousInit","vm","listener","audio","screen","reportWarnings","emitBridgeEvent","updateSource","file","src","reinit","cancelBeeps","clear","run","error_info","err","Object","assign","type","reportError","runner","getFunctionSource","init","call"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -17,8 +17,6 @@ export { deepClone } from './utils/deep-clone.mjs';
|
|
|
17
17
|
export { ObjectPool } from './utils/object-pool.mjs';
|
|
18
18
|
export { shallowEqual } from './utils/shallow-equal.mjs';
|
|
19
19
|
import '@al8b/player';
|
|
20
|
-
import '@al8b/scene';
|
|
21
20
|
import '@al8b/screen';
|
|
22
21
|
import '@al8b/time';
|
|
23
22
|
import '@al8b/input';
|
|
24
|
-
import '@al8b/framework-shared';
|
package/dist/index.d.ts
CHANGED
|
@@ -17,8 +17,6 @@ export { deepClone } from './utils/deep-clone.js';
|
|
|
17
17
|
export { ObjectPool } from './utils/object-pool.js';
|
|
18
18
|
export { shallowEqual } from './utils/shallow-equal.js';
|
|
19
19
|
import '@al8b/player';
|
|
20
|
-
import '@al8b/scene';
|
|
21
20
|
import '@al8b/screen';
|
|
22
21
|
import '@al8b/time';
|
|
23
22
|
import '@al8b/input';
|
|
24
|
-
import '@al8b/framework-shared';
|
package/dist/index.js
CHANGED
|
@@ -284,7 +284,6 @@ var AssetLoader = class {
|
|
|
284
284
|
// src/core/controller.ts
|
|
285
285
|
var import_audio3 = require("@al8b/audio");
|
|
286
286
|
var import_player = require("@al8b/player");
|
|
287
|
-
var import_scene = require("@al8b/scene");
|
|
288
287
|
var import_screen = require("@al8b/screen");
|
|
289
288
|
var import_time = require("@al8b/time");
|
|
290
289
|
var import_vm2 = require("@al8b/vm");
|
|
@@ -766,29 +765,14 @@ function shallowEqual(obj1, obj2) {
|
|
|
766
765
|
__name(shallowEqual, "shallowEqual");
|
|
767
766
|
|
|
768
767
|
// src/core/error-handler.ts
|
|
769
|
-
var import_diagnostics = require("@al8b/diagnostics");
|
|
770
768
|
function formatRuntimeError(error) {
|
|
771
769
|
if (error.code || error.context || error.suggestions) {
|
|
772
770
|
return error;
|
|
773
771
|
}
|
|
774
|
-
const code = error.code || "E2005";
|
|
775
|
-
const diagnostic = (0, import_diagnostics.createDiagnostic)(code, {
|
|
776
|
-
file: error.file,
|
|
777
|
-
line: error.line,
|
|
778
|
-
column: error.column,
|
|
779
|
-
context: error.context,
|
|
780
|
-
suggestions: error.suggestions,
|
|
781
|
-
related: error.related,
|
|
782
|
-
stackTrace: error.stackTrace,
|
|
783
|
-
data: {
|
|
784
|
-
error: error.error || error.message
|
|
785
|
-
}
|
|
786
|
-
});
|
|
787
|
-
const formattedMessage = (0, import_diagnostics.formatForBrowser)(diagnostic);
|
|
788
772
|
return {
|
|
789
773
|
...error,
|
|
790
|
-
|
|
791
|
-
formatted:
|
|
774
|
+
code: error.code || "E2005",
|
|
775
|
+
formatted: error.message || String(error)
|
|
792
776
|
};
|
|
793
777
|
}
|
|
794
778
|
__name(formatRuntimeError, "formatRuntimeError");
|
|
@@ -1020,12 +1004,6 @@ function createRuntimeGlobalApi(context) {
|
|
|
1020
1004
|
session,
|
|
1021
1005
|
memory,
|
|
1022
1006
|
system: context.system.getAPI(),
|
|
1023
|
-
scene: /* @__PURE__ */ __name((name, definition) => {
|
|
1024
|
-
const convertedDefinition = convertSceneDefinition(asSceneDefinition(definition), context.getVM(), context.listener);
|
|
1025
|
-
context.sceneManager.registerScene(name, convertedDefinition);
|
|
1026
|
-
}, "scene"),
|
|
1027
|
-
route: /* @__PURE__ */ __name((path, sceneName) => context.sceneManager.registerRoute(path, sceneName), "route"),
|
|
1028
|
-
router: context.sceneManager.router.getInterface(),
|
|
1029
1007
|
Image: import_image.Image,
|
|
1030
1008
|
Sprite: import_sprites.Sprite,
|
|
1031
1009
|
TileMap: import_map.TileMap,
|
|
@@ -1036,40 +1014,27 @@ function createRuntimeGlobalApi(context) {
|
|
|
1036
1014
|
};
|
|
1037
1015
|
}
|
|
1038
1016
|
__name(createRuntimeGlobalApi, "createRuntimeGlobalApi");
|
|
1039
|
-
function convertSceneDefinition(definition, vm, listener) {
|
|
1040
|
-
if (!vm?.runner?.main_thread?.processor) {
|
|
1041
|
-
listener.log?.("[RuntimeController] VM not ready for scene conversion. Scene functions may not work correctly.");
|
|
1042
|
-
return definition;
|
|
1043
|
-
}
|
|
1044
|
-
const processor = vm.runner.main_thread.processor;
|
|
1045
|
-
const context = vm.context;
|
|
1046
|
-
const converted = {};
|
|
1047
|
-
for (const [key, value] of Object.entries(definition)) {
|
|
1048
|
-
if (value instanceof import_vm.Routine) {
|
|
1049
|
-
converted[key] = processor.routineAsFunction(value, context);
|
|
1050
|
-
continue;
|
|
1051
|
-
}
|
|
1052
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1053
|
-
converted[key] = convertSceneDefinition(value, vm, listener);
|
|
1054
|
-
continue;
|
|
1055
|
-
}
|
|
1056
|
-
converted[key] = value;
|
|
1057
|
-
}
|
|
1058
|
-
return converted;
|
|
1059
|
-
}
|
|
1060
|
-
__name(convertSceneDefinition, "convertSceneDefinition");
|
|
1061
|
-
function asSceneDefinition(definition) {
|
|
1062
|
-
if (!definition || typeof definition !== "object" || Array.isArray(definition)) {
|
|
1063
|
-
throw new Error("Scene definition must be an object.");
|
|
1064
|
-
}
|
|
1065
|
-
return definition;
|
|
1066
|
-
}
|
|
1067
|
-
__name(asSceneDefinition, "asSceneDefinition");
|
|
1068
1017
|
function cloneValue(value) {
|
|
1069
1018
|
if (value == null) {
|
|
1070
1019
|
return value;
|
|
1071
1020
|
}
|
|
1072
|
-
|
|
1021
|
+
if (value instanceof Date) {
|
|
1022
|
+
return new Date(value);
|
|
1023
|
+
}
|
|
1024
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1025
|
+
return value;
|
|
1026
|
+
}
|
|
1027
|
+
if (Array.isArray(value)) {
|
|
1028
|
+
return value.map((entry) => cloneValue(entry));
|
|
1029
|
+
}
|
|
1030
|
+
if (typeof value === "object") {
|
|
1031
|
+
const clone = {};
|
|
1032
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
1033
|
+
clone[key] = cloneValue(entry);
|
|
1034
|
+
}
|
|
1035
|
+
return clone;
|
|
1036
|
+
}
|
|
1037
|
+
return null;
|
|
1073
1038
|
}
|
|
1074
1039
|
__name(cloneValue, "cloneValue");
|
|
1075
1040
|
|
|
@@ -1102,7 +1067,6 @@ var RuntimeControllerImpl = class {
|
|
|
1102
1067
|
input;
|
|
1103
1068
|
system;
|
|
1104
1069
|
playerService;
|
|
1105
|
-
sceneManager;
|
|
1106
1070
|
vm = null;
|
|
1107
1071
|
timeMachine = null;
|
|
1108
1072
|
constructor(options = {}) {
|
|
@@ -1129,7 +1093,6 @@ var RuntimeControllerImpl = class {
|
|
|
1129
1093
|
this.system.getAPI().update_rate = rate;
|
|
1130
1094
|
}, "setUpdateRate")
|
|
1131
1095
|
});
|
|
1132
|
-
this.sceneManager = new import_scene.SceneManager();
|
|
1133
1096
|
this.assetLoader = new AssetLoader(options.url || "", options.resources || {}, this.audio, this.listener);
|
|
1134
1097
|
this.logStep("RuntimeController constructed", {
|
|
1135
1098
|
width: this.screen.width,
|
|
@@ -1217,15 +1180,10 @@ var RuntimeControllerImpl = class {
|
|
|
1217
1180
|
}
|
|
1218
1181
|
exportSnapshot() {
|
|
1219
1182
|
const global = this.vm?.context?.global;
|
|
1220
|
-
const routerState = this.sceneManager.router.getState();
|
|
1221
1183
|
return {
|
|
1222
1184
|
version: 1,
|
|
1223
1185
|
global: global ? serializeGlobalSnapshot(global) : {},
|
|
1224
1186
|
session: this.getSession(),
|
|
1225
|
-
router: {
|
|
1226
|
-
path: routerState.path,
|
|
1227
|
-
sceneName: this.sceneManager.getCurrentSceneName()
|
|
1228
|
-
},
|
|
1229
1187
|
system: {
|
|
1230
1188
|
updateRate: this.system.getAPI().update_rate
|
|
1231
1189
|
}
|
|
@@ -1241,11 +1199,6 @@ var RuntimeControllerImpl = class {
|
|
|
1241
1199
|
if (snapshot.session) {
|
|
1242
1200
|
this.sessionSnapshot = cloneSnapshot(snapshot.session);
|
|
1243
1201
|
}
|
|
1244
|
-
if (snapshot.router.path) {
|
|
1245
|
-
this.sceneManager.router.replace(snapshot.router.path);
|
|
1246
|
-
} else if (snapshot.router.sceneName) {
|
|
1247
|
-
this.sceneManager.setActiveScene(snapshot.router.sceneName);
|
|
1248
|
-
}
|
|
1249
1202
|
}
|
|
1250
1203
|
updateSource(file, src, reinit = false) {
|
|
1251
1204
|
if (!this.sourceUpdater) return false;
|
|
@@ -1299,7 +1252,6 @@ var RuntimeControllerImpl = class {
|
|
|
1299
1252
|
input: this.input,
|
|
1300
1253
|
system: this.system,
|
|
1301
1254
|
playerService: this.playerService,
|
|
1302
|
-
sceneManager: this.sceneManager,
|
|
1303
1255
|
assets: this.assetRegistry,
|
|
1304
1256
|
bridge: this.options.bridge,
|
|
1305
1257
|
getVM: /* @__PURE__ */ __name(() => this.vm, "getVM"),
|
|
@@ -1323,7 +1275,6 @@ var RuntimeControllerImpl = class {
|
|
|
1323
1275
|
});
|
|
1324
1276
|
});
|
|
1325
1277
|
this.loadPrograms();
|
|
1326
|
-
this.initializeScenesAndRouter();
|
|
1327
1278
|
this.emitBridgeEvent("runtime.started", {});
|
|
1328
1279
|
}
|
|
1329
1280
|
loadPrograms() {
|
|
@@ -1377,21 +1328,6 @@ var RuntimeControllerImpl = class {
|
|
|
1377
1328
|
});
|
|
1378
1329
|
}
|
|
1379
1330
|
}
|
|
1380
|
-
initializeScenesAndRouter() {
|
|
1381
|
-
const registeredScenes = this.sceneManager.registry.getNames();
|
|
1382
|
-
this.logStep("router: initializing", {
|
|
1383
|
-
registeredScenes: registeredScenes.length,
|
|
1384
|
-
sceneNames: registeredScenes
|
|
1385
|
-
});
|
|
1386
|
-
this.sceneManager.router.init();
|
|
1387
|
-
const activeScene = this.sceneManager.hasActiveScene() ? this.sceneManager.getCurrentSceneName?.() || "unknown" : null;
|
|
1388
|
-
const routerState = this.sceneManager.router.getState();
|
|
1389
|
-
this.logStep("router: initialized", {
|
|
1390
|
-
activeScene: activeScene || "none",
|
|
1391
|
-
path: routerState.path,
|
|
1392
|
-
hasActiveScene: this.sceneManager.hasActiveScene()
|
|
1393
|
-
});
|
|
1394
|
-
}
|
|
1395
1331
|
startGameLoop() {
|
|
1396
1332
|
this.logStep("loop: creating game loop");
|
|
1397
1333
|
this.gameLoop = new GameLoop({
|
|
@@ -1445,12 +1381,8 @@ var RuntimeControllerImpl = class {
|
|
|
1445
1381
|
this.updateGameLoopUpdateRate();
|
|
1446
1382
|
}
|
|
1447
1383
|
try {
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
} else {
|
|
1451
|
-
this.vm.call("update");
|
|
1452
|
-
this.vm.runner.tick();
|
|
1453
|
-
}
|
|
1384
|
+
this.vm.call("update");
|
|
1385
|
+
this.vm.runner.tick();
|
|
1454
1386
|
if (this.vm.error_info) {
|
|
1455
1387
|
const err = Object.assign({}, this.vm.error_info);
|
|
1456
1388
|
err.type = "update";
|
|
@@ -1469,12 +1401,8 @@ var RuntimeControllerImpl = class {
|
|
|
1469
1401
|
try {
|
|
1470
1402
|
this.screen.initDraw();
|
|
1471
1403
|
this.screen.updateInterface();
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
} else {
|
|
1475
|
-
this.vm.call("draw");
|
|
1476
|
-
this.vm.runner.tick();
|
|
1477
|
-
}
|
|
1404
|
+
this.vm.call("draw");
|
|
1405
|
+
this.vm.runner.tick();
|
|
1478
1406
|
reportWarnings(this.vm, this.listener);
|
|
1479
1407
|
if (this.vm.error_info) {
|
|
1480
1408
|
const err = Object.assign({}, this.vm.error_info);
|
|
@@ -1700,8 +1628,6 @@ var RuntimeControllerImpl = class {
|
|
|
1700
1628
|
this.frameCount = 0;
|
|
1701
1629
|
this.lastUpdateRate = -1;
|
|
1702
1630
|
this.isStopped = false;
|
|
1703
|
-
this.sceneManager.registry.clear();
|
|
1704
|
-
this.sceneManager.routeManager.clear();
|
|
1705
1631
|
}
|
|
1706
1632
|
logStep(message, payload) {
|
|
1707
1633
|
if (!this.options.debug?.lifecycle) return;
|
|
@@ -1787,7 +1713,6 @@ function isRuntimeSnapshot(value) {
|
|
|
1787
1713
|
if (!isRecord(value)) return false;
|
|
1788
1714
|
if (value.version !== 1) return false;
|
|
1789
1715
|
if (!isRecord(value.global)) return false;
|
|
1790
|
-
if (!("router" in value)) return false;
|
|
1791
1716
|
if (!("session" in value)) return false;
|
|
1792
1717
|
return true;
|
|
1793
1718
|
}
|