@typecad/cuttlefish 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +79 -0
- package/dist/api/board-types.d.ts +1 -0
- package/dist/api/board-types.js +4 -0
- package/dist/api/capabilities.d.ts +12 -0
- package/dist/api/capabilities.js +1 -0
- package/dist/api/config.d.ts +120 -0
- package/dist/api/config.js +7 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.js +2 -0
- package/dist/api/schema/builder.d.ts +14 -0
- package/dist/api/schema/builder.js +15 -0
- package/dist/api/schema/index.d.ts +2 -0
- package/dist/api/schema/index.js +1 -0
- package/dist/api/schema/types.d.ts +257 -0
- package/dist/api/schema/types.js +4 -0
- package/dist/api/shared/async-runtime-static.d.ts +8 -0
- package/dist/api/shared/async-runtime-static.js +201 -0
- package/dist/api/shared/async-types.d.ts +42 -0
- package/dist/api/shared/async-types.js +8 -0
- package/dist/api/shared/board-resolver.d.ts +12 -0
- package/dist/api/shared/board-resolver.js +7 -0
- package/dist/api/shared/cpp-type-ir.d.ts +229 -0
- package/dist/api/shared/cpp-type-ir.js +672 -0
- package/dist/api/shared/display-adapter.d.ts +12 -0
- package/dist/api/shared/display-adapter.js +145 -0
- package/dist/api/shared/display-adapters/eink-mono.d.ts +2 -0
- package/dist/api/shared/display-adapters/eink-mono.js +53 -0
- package/dist/api/shared/display-adapters/sdl.d.ts +2 -0
- package/dist/api/shared/display-adapters/sdl.js +452 -0
- package/dist/api/shared/display-adapters/ssd1309.d.ts +2 -0
- package/dist/api/shared/display-adapters/ssd1309.js +136 -0
- package/dist/api/shared/display-adapters/st7796.d.ts +2 -0
- package/dist/api/shared/display-adapters/st7796.js +132 -0
- package/dist/api/shared/display-capabilities.d.ts +45 -0
- package/dist/api/shared/display-capabilities.js +54 -0
- package/dist/api/shared/display-op-ir.d.ts +62 -0
- package/dist/api/shared/display-op-ir.js +19 -0
- package/dist/api/shared/display-profile.d.ts +265 -0
- package/dist/api/shared/display-profile.js +338 -0
- package/dist/api/shared/graphics-strategy.d.ts +29 -0
- package/dist/api/shared/graphics-strategy.js +11 -0
- package/dist/api/shared/hal-op-ir.d.ts +393 -0
- package/dist/api/shared/hal-op-ir.js +18 -0
- package/dist/api/shared/index.d.ts +26 -0
- package/dist/api/shared/index.js +21 -0
- package/dist/api/shared/ir-core.d.ts +363 -0
- package/dist/api/shared/ir-core.js +8 -0
- package/dist/api/shared/ir-declarations.d.ts +201 -0
- package/dist/api/shared/ir-declarations.js +26 -0
- package/dist/api/shared/ir.d.ts +85 -0
- package/dist/api/shared/ir.js +13 -0
- package/dist/api/shared/platform-strategy.d.ts +402 -0
- package/dist/api/shared/platform-strategy.js +14 -0
- package/dist/api/shared/polyfill-helper-registry.d.ts +11 -0
- package/dist/api/shared/polyfill-helper-registry.js +86 -0
- package/dist/api/shared/polyfill-types.d.ts +33 -0
- package/dist/api/shared/polyfill-types.js +76 -0
- package/dist/api/shared/promise-runtime.d.ts +10 -0
- package/dist/api/shared/promise-runtime.js +244 -0
- package/dist/api/shared/snprintf-types.d.ts +29 -0
- package/dist/api/shared/snprintf-types.js +8 -0
- package/dist/api/shared/string-method-registry.d.ts +53 -0
- package/dist/api/shared/string-method-registry.js +168 -0
- package/dist/api/shared/toolchain-types.d.ts +63 -0
- package/dist/api/shared/toolchain-types.js +71 -0
- package/dist/api/shared/types.d.ts +50 -0
- package/dist/api/shared/types.js +6 -0
- package/dist/ast/parse.d.ts +2 -0
- package/dist/ast/parse.js +4 -0
- package/dist/cache.d.ts +26 -0
- package/dist/cache.js +95 -0
- package/dist/cli-utils.d.ts +37 -0
- package/dist/cli-utils.js +250 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +635 -0
- package/dist/config-loader.d.ts +78 -0
- package/dist/config-loader.js +508 -0
- package/dist/config-schema.d.ts +233 -0
- package/dist/config-schema.js +83 -0
- package/dist/create/board-checklist.d.ts +2 -0
- package/dist/create/board-checklist.js +52 -0
- package/dist/create/board-codegen.d.ts +9 -0
- package/dist/create/board-codegen.js +238 -0
- package/dist/create/board-generators.d.ts +12 -0
- package/dist/create/board-generators.js +652 -0
- package/dist/create/board-spec.d.ts +640 -0
- package/dist/create/board-spec.js +215 -0
- package/dist/create/eslint-rules-template.d.ts +2 -0
- package/dist/create/eslint-rules-template.js +672 -0
- package/dist/create/index.d.ts +11 -0
- package/dist/create/index.js +8 -0
- package/dist/create/init-scaffold.d.ts +27 -0
- package/dist/create/init-scaffold.js +150 -0
- package/dist/create/init-templates.d.ts +24 -0
- package/dist/create/init-templates.js +379 -0
- package/dist/create/init-wizard.d.ts +8 -0
- package/dist/create/init-wizard.js +168 -0
- package/dist/debug/breakpoint-loader.d.ts +24 -0
- package/dist/debug/breakpoint-loader.js +137 -0
- package/dist/debug/index.d.ts +3 -0
- package/dist/debug/index.js +7 -0
- package/dist/debug/preprocessor.d.ts +9 -0
- package/dist/debug/preprocessor.js +214 -0
- package/dist/debug/types.d.ts +32 -0
- package/dist/debug/types.js +6 -0
- package/dist/diagnostics/diagnostics-report.d.ts +51 -0
- package/dist/diagnostics/diagnostics-report.js +333 -0
- package/dist/diagnostics/json-schema.d.ts +138 -0
- package/dist/diagnostics/json-schema.js +27 -0
- package/dist/diagnostics/md-writer.d.ts +10 -0
- package/dist/diagnostics/md-writer.js +336 -0
- package/dist/diagnostics/mermaid-builder.d.ts +65 -0
- package/dist/diagnostics/mermaid-builder.js +681 -0
- package/dist/emit/cpp-emitter.d.ts +6 -0
- package/dist/emit/cpp-emitter.js +48 -0
- package/dist/emit/emitters/class-emitter.d.ts +2 -0
- package/dist/emit/emitters/class-emitter.js +523 -0
- package/dist/emit/emitters/emitter-context.d.ts +174 -0
- package/dist/emit/emitters/emitter-context.js +1 -0
- package/dist/emit/emitters/entrypoint-synthesizer.d.ts +2 -0
- package/dist/emit/emitters/entrypoint-synthesizer.js +175 -0
- package/dist/emit/emitters/function-emitter-impl.d.ts +19 -0
- package/dist/emit/emitters/function-emitter-impl.js +428 -0
- package/dist/emit/emitters/line-appender.d.ts +15 -0
- package/dist/emit/emitters/line-appender.js +344 -0
- package/dist/emit/emitters/namespace-emitter.d.ts +2 -0
- package/dist/emit/emitters/namespace-emitter.js +324 -0
- package/dist/emit/emitters/output-finalizer.d.ts +4 -0
- package/dist/emit/emitters/output-finalizer.js +267 -0
- package/dist/emit/emitters/setup.d.ts +3 -0
- package/dist/emit/emitters/setup.js +851 -0
- package/dist/emit/emitters/top-level-prep.d.ts +2 -0
- package/dist/emit/emitters/top-level-prep.js +706 -0
- package/dist/emit/emitters/type-decl-emitter.d.ts +2 -0
- package/dist/emit/emitters/type-decl-emitter.js +251 -0
- package/dist/emit/emitters/ui-emitter.d.ts +21 -0
- package/dist/emit/emitters/ui-emitter.js +564 -0
- package/dist/emit/enum-emitter.d.ts +1 -0
- package/dist/emit/enum-emitter.js +1 -0
- package/dist/emit/expression-renderer.d.ts +283 -0
- package/dist/emit/expression-renderer.js +1477 -0
- package/dist/emit/native-helpers-emitter.d.ts +11 -0
- package/dist/emit/native-helpers-emitter.js +34 -0
- package/dist/emit/route-hal-op.d.ts +5 -0
- package/dist/emit/route-hal-op.js +13 -0
- package/dist/emit/snprintf-helpers.d.ts +17 -0
- package/dist/emit/snprintf-helpers.js +462 -0
- package/dist/emit/statement-renderer.d.ts +189 -0
- package/dist/emit/statement-renderer.js +948 -0
- package/dist/emit/utils/async-state-machine.d.ts +42 -0
- package/dist/emit/utils/async-state-machine.js +343 -0
- package/dist/emit/utils/comment-helpers.d.ts +20 -0
- package/dist/emit/utils/comment-helpers.js +31 -0
- package/dist/emit/utils/cpp-helpers.d.ts +47 -0
- package/dist/emit/utils/cpp-helpers.js +85 -0
- package/dist/emit/utils/include-resolver.d.ts +58 -0
- package/dist/emit/utils/include-resolver.js +155 -0
- package/dist/emit/utils/index.d.ts +8 -0
- package/dist/emit/utils/index.js +12 -0
- package/dist/emit/utils/type-inference.d.ts +159 -0
- package/dist/emit/utils/type-inference.js +559 -0
- package/dist/eslint-check.d.ts +10 -0
- package/dist/eslint-check.js +102 -0
- package/dist/framework-package.d.ts +10 -0
- package/dist/framework-package.js +58 -0
- package/dist/framework-registry.d.ts +39 -0
- package/dist/framework-registry.js +30 -0
- package/dist/incremental-cache.d.ts +116 -0
- package/dist/incremental-cache.js +335 -0
- package/dist/ir/adc-range-validation.d.ts +11 -0
- package/dist/ir/adc-range-validation.js +250 -0
- package/dist/ir/ast-node-utils.d.ts +8 -0
- package/dist/ir/ast-node-utils.js +32 -0
- package/dist/ir/board-pin-utils.d.ts +13 -0
- package/dist/ir/board-pin-utils.js +65 -0
- package/dist/ir/board-resolver.d.ts +36 -0
- package/dist/ir/board-resolver.js +437 -0
- package/dist/ir/build-ir-state.d.ts +167 -0
- package/dist/ir/build-ir-state.js +306 -0
- package/dist/ir/build-ir.d.ts +2 -0
- package/dist/ir/build-ir.js +808 -0
- package/dist/ir/call-graph.d.ts +35 -0
- package/dist/ir/call-graph.js +194 -0
- package/dist/ir/compile-time-only.d.ts +2 -0
- package/dist/ir/compile-time-only.js +16 -0
- package/dist/ir/declaration-builders.d.ts +9 -0
- package/dist/ir/declaration-builders.js +608 -0
- package/dist/ir/entry-points.d.ts +30 -0
- package/dist/ir/entry-points.js +191 -0
- package/dist/ir/expression-to-ir.d.ts +5 -0
- package/dist/ir/expression-to-ir.js +2249 -0
- package/dist/ir/extract-property-chain.d.ts +10 -0
- package/dist/ir/extract-property-chain.js +30 -0
- package/dist/ir/feature-prescan.d.ts +3 -0
- package/dist/ir/feature-prescan.js +43 -0
- package/dist/ir/feature-registry.d.ts +30 -0
- package/dist/ir/feature-registry.js +816 -0
- package/dist/ir/filter.d.ts +7 -0
- package/dist/ir/filter.js +85 -0
- package/dist/ir/function-builder.d.ts +19 -0
- package/dist/ir/function-builder.js +670 -0
- package/dist/ir/hal/hal-emitter.d.ts +62 -0
- package/dist/ir/hal/hal-emitter.js +735 -0
- package/dist/ir/hal/hal-parser.d.ts +61 -0
- package/dist/ir/hal/hal-parser.js +473 -0
- package/dist/ir/hal/hal-plugins.d.ts +34 -0
- package/dist/ir/hal/hal-plugins.js +706 -0
- package/dist/ir/hal-resolver.d.ts +5 -0
- package/dist/ir/hal-resolver.js +5 -0
- package/dist/ir/heap-analysis.d.ts +8 -0
- package/dist/ir/heap-analysis.js +350 -0
- package/dist/ir/heap-array-validation.d.ts +24 -0
- package/dist/ir/heap-array-validation.js +29 -0
- package/dist/ir/identifier-collector.d.ts +18 -0
- package/dist/ir/identifier-collector.js +439 -0
- package/dist/ir/interrupt-analysis.d.ts +39 -0
- package/dist/ir/interrupt-analysis.js +467 -0
- package/dist/ir/memory-budget-validation.d.ts +10 -0
- package/dist/ir/memory-budget-validation.js +86 -0
- package/dist/ir/namespace-builder.d.ts +7 -0
- package/dist/ir/namespace-builder.js +152 -0
- package/dist/ir/ownership-analysis.d.ts +9 -0
- package/dist/ir/ownership-analysis.js +1207 -0
- package/dist/ir/peripheral-ownership.d.ts +3 -0
- package/dist/ir/peripheral-ownership.js +152 -0
- package/dist/ir/peripheral-symbols.d.ts +7 -0
- package/dist/ir/peripheral-symbols.js +57 -0
- package/dist/ir/peripheral-usage.d.ts +54 -0
- package/dist/ir/peripheral-usage.js +691 -0
- package/dist/ir/peripheral-validation.d.ts +8 -0
- package/dist/ir/peripheral-validation.js +77 -0
- package/dist/ir/pin-alias-conflict.d.ts +4 -0
- package/dist/ir/pin-alias-conflict.js +34 -0
- package/dist/ir/pin-capability-validation.d.ts +6 -0
- package/dist/ir/pin-capability-validation.js +413 -0
- package/dist/ir/pin-mode-validation.d.ts +10 -0
- package/dist/ir/pin-mode-validation.js +301 -0
- package/dist/ir/pin-safety.d.ts +11 -0
- package/dist/ir/pin-safety.js +58 -0
- package/dist/ir/program-analysis.d.ts +44 -0
- package/dist/ir/program-analysis.js +589 -0
- package/dist/ir/pulldown-validation.d.ts +7 -0
- package/dist/ir/pulldown-validation.js +49 -0
- package/dist/ir/pwm-timer-sharing.d.ts +4 -0
- package/dist/ir/pwm-timer-sharing.js +93 -0
- package/dist/ir/reachability.d.ts +68 -0
- package/dist/ir/reachability.js +224 -0
- package/dist/ir/register-decorators.d.ts +6 -0
- package/dist/ir/register-decorators.js +49 -0
- package/dist/ir/render-expr.d.ts +4 -0
- package/dist/ir/render-expr.js +127 -0
- package/dist/ir/resource-analysis.d.ts +19 -0
- package/dist/ir/resource-analysis.js +153 -0
- package/dist/ir/statement-to-ir.d.ts +23 -0
- package/dist/ir/statement-to-ir.js +349 -0
- package/dist/ir/symbol-table.d.ts +68 -0
- package/dist/ir/symbol-table.js +179 -0
- package/dist/ir/symbol-types.d.ts +56 -0
- package/dist/ir/symbol-types.js +107 -0
- package/dist/ir/timer0-pwm-timing-conflict.d.ts +4 -0
- package/dist/ir/timer0-pwm-timing-conflict.js +71 -0
- package/dist/ir/timing-validation.d.ts +7 -0
- package/dist/ir/timing-validation.js +95 -0
- package/dist/ir/transformers/array-methods.d.ts +8 -0
- package/dist/ir/transformers/array-methods.js +493 -0
- package/dist/ir/transformers/call-statement.d.ts +5 -0
- package/dist/ir/transformers/call-statement.js +758 -0
- package/dist/ir/transformers/callback-context-registry.d.ts +20 -0
- package/dist/ir/transformers/callback-context-registry.js +55 -0
- package/dist/ir/transformers/canvas-lowering.d.ts +42 -0
- package/dist/ir/transformers/canvas-lowering.js +249 -0
- package/dist/ir/transformers/control-flow.d.ts +8 -0
- package/dist/ir/transformers/control-flow.js +508 -0
- package/dist/ir/transformers/expressions.d.ts +7 -0
- package/dist/ir/transformers/expressions.js +406 -0
- package/dist/ir/transformers/hal-call-resolver.d.ts +29 -0
- package/dist/ir/transformers/hal-call-resolver.js +274 -0
- package/dist/ir/transformers/hal-emit-helpers.d.ts +14 -0
- package/dist/ir/transformers/hal-emit-helpers.js +63 -0
- package/dist/ir/transformers/namespace-methods.d.ts +20 -0
- package/dist/ir/transformers/namespace-methods.js +110 -0
- package/dist/ir/transformers/register-assignment.d.ts +5 -0
- package/dist/ir/transformers/register-assignment.js +56 -0
- package/dist/ir/transformers/ui-call-resolver.d.ts +149 -0
- package/dist/ir/transformers/ui-call-resolver.js +1136 -0
- package/dist/ir/transformers/ui-callback-lowering.d.ts +62 -0
- package/dist/ir/transformers/ui-callback-lowering.js +623 -0
- package/dist/ir/transformers/ui-mount.d.ts +20 -0
- package/dist/ir/transformers/ui-mount.js +35 -0
- package/dist/ir/transformers/ui-reactive.d.ts +68 -0
- package/dist/ir/transformers/ui-reactive.js +129 -0
- package/dist/ir/transformers/variables.d.ts +14 -0
- package/dist/ir/transformers/variables.js +1045 -0
- package/dist/ir/try-catch-validation.d.ts +26 -0
- package/dist/ir/try-catch-validation.js +128 -0
- package/dist/ir/type-resolution.d.ts +31 -0
- package/dist/ir/type-resolution.js +977 -0
- package/dist/ir/ui-element-auto-wire.d.ts +50 -0
- package/dist/ir/ui-element-auto-wire.js +218 -0
- package/dist/ir/unit-suspicion-validation.d.ts +12 -0
- package/dist/ir/unit-suspicion-validation.js +296 -0
- package/dist/ir/utils/walk-ir.d.ts +6 -0
- package/dist/ir/utils/walk-ir.js +162 -0
- package/dist/ir/validation-orchestrator.d.ts +4 -0
- package/dist/ir/validation-orchestrator.js +45 -0
- package/dist/libdef/base-class-resolver.d.ts +23 -0
- package/dist/libdef/base-class-resolver.js +50 -0
- package/dist/libdef/cpp-to-decl.d.ts +34 -0
- package/dist/libdef/cpp-to-decl.js +584 -0
- package/dist/libdef/header-parser.d.ts +53 -0
- package/dist/libdef/header-parser.js +269 -0
- package/dist/libdef/registry.d.ts +10 -0
- package/dist/libdef/registry.js +142 -0
- package/dist/mapping/peripheral-names.d.ts +23 -0
- package/dist/mapping/peripheral-names.js +63 -0
- package/dist/mapping/source-map.d.ts +46 -0
- package/dist/mapping/source-map.js +207 -0
- package/dist/orchestrator/dts-generator.d.ts +17 -0
- package/dist/orchestrator/dts-generator.js +83 -0
- package/dist/orchestrator/graph-builder.d.ts +18 -0
- package/dist/orchestrator/graph-builder.js +218 -0
- package/dist/orchestrator/semantic-facts-verifier.d.ts +38 -0
- package/dist/orchestrator/semantic-facts-verifier.js +121 -0
- package/dist/orchestrator/semantic-facts.d.ts +141 -0
- package/dist/orchestrator/semantic-facts.js +652 -0
- package/dist/orchestrator/type-checker.d.ts +39 -0
- package/dist/orchestrator/type-checker.js +760 -0
- package/dist/platform/async-runtime.d.ts +8 -0
- package/dist/platform/async-runtime.js +26 -0
- package/dist/platform/generic-strategy.d.ts +101 -0
- package/dist/platform/generic-strategy.js +289 -0
- package/dist/platform/index.d.ts +4 -0
- package/dist/platform/index.js +9 -0
- package/dist/platform/registry.d.ts +21 -0
- package/dist/platform/registry.js +42 -0
- package/dist/platform/toolchain.d.ts +4 -0
- package/dist/platform/toolchain.js +43 -0
- package/dist/preview/client.d.ts +1 -0
- package/dist/preview/client.js +137 -0
- package/dist/preview/server.d.ts +5 -0
- package/dist/preview/server.js +199 -0
- package/dist/profiler/index.d.ts +28 -0
- package/dist/profiler/index.js +28 -0
- package/dist/profiler/profiler.d.ts +95 -0
- package/dist/profiler/profiler.js +338 -0
- package/dist/profiler/types.d.ts +87 -0
- package/dist/profiler/types.js +12 -0
- package/dist/stores/display-profile-store.d.ts +16 -0
- package/dist/stores/display-profile-store.js +48 -0
- package/dist/stores/theme-store.d.ts +13 -0
- package/dist/stores/theme-store.js +30 -0
- package/dist/testing.d.ts +45 -0
- package/dist/testing.js +47 -0
- package/dist/transpile/resolution.d.ts +29 -0
- package/dist/transpile/resolution.js +282 -0
- package/dist/transpile.d.ts +3 -0
- package/dist/transpile.js +722 -0
- package/dist/types.d.ts +217 -0
- package/dist/types.js +1 -0
- package/dist/ui/ui-bridge.d.ts +4 -0
- package/dist/ui/ui-bridge.js +34 -0
- package/dist/ui-hook.d.ts +84 -0
- package/dist/ui-hook.js +45 -0
- package/dist/utils/cli.d.ts +3 -0
- package/dist/utils/cli.js +463 -0
- package/dist/utils/fs.d.ts +4 -0
- package/dist/utils/fs.js +23 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +8 -0
- package/dist/utils/strings.d.ts +35 -0
- package/dist/utils/strings.js +142 -0
- package/dist/utils/ui.d.ts +66 -0
- package/dist/utils/ui.js +149 -0
- package/dist/watch.d.ts +35 -0
- package/dist/watch.js +111 -0
- package/package.json +127 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { setLoadedFramework } from "./framework-registry.js";
|
|
4
|
+
import { registerPlatformStrategy } from "./platform/registry.js";
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
function resolveFrameworkPackage(packageName, fromDir = process.cwd()) {
|
|
7
|
+
try {
|
|
8
|
+
const resolved = require.resolve(packageName, { paths: [path.resolve(fromDir)] });
|
|
9
|
+
return resolved;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Extract toolchain operations from a loaded framework module.
|
|
17
|
+
* Frameworks export a `Toolchain` object implementing FrameworkToolchain.
|
|
18
|
+
*/
|
|
19
|
+
function extractToolchain(mod) {
|
|
20
|
+
if (mod.Toolchain && typeof mod.Toolchain === "object") {
|
|
21
|
+
return mod.Toolchain;
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Load a framework package and populate the LoadedFramework registry.
|
|
27
|
+
*
|
|
28
|
+
* The loaded module is expected to export at minimum `FrameworkStrategy`.
|
|
29
|
+
* Optional exports include `Toolchain`, `SYMBOL_KINDS`, library resolver,
|
|
30
|
+
* class name map builder, and lib declaration generator.
|
|
31
|
+
*
|
|
32
|
+
* Returns the raw module for backward compatibility.
|
|
33
|
+
*/
|
|
34
|
+
export function loadFrameworkPackage(packageName, fromDir = process.cwd()) {
|
|
35
|
+
const packagePath = resolveFrameworkPackage(packageName, fromDir);
|
|
36
|
+
if (!packagePath) {
|
|
37
|
+
throw new Error(`Unable to resolve framework package '${packageName}' from '${fromDir}'. ` +
|
|
38
|
+
`Install it or pass a different framework package name in your TypeCAD config.`);
|
|
39
|
+
}
|
|
40
|
+
const mod = require(packagePath);
|
|
41
|
+
// Populate the registry with the loaded framework components
|
|
42
|
+
if (mod.FrameworkStrategy) {
|
|
43
|
+
const strategy = new mod.FrameworkStrategy();
|
|
44
|
+
const framework = {
|
|
45
|
+
strategy,
|
|
46
|
+
toolchain: extractToolchain(mod),
|
|
47
|
+
libraryResolver: typeof mod.isFrameworkLibraryImport === "function" ? {
|
|
48
|
+
isFrameworkLibraryImport: mod.isFrameworkLibraryImport,
|
|
49
|
+
getFrameworkLibraryHeaderName: mod.getFrameworkLibraryHeaderName,
|
|
50
|
+
} : undefined,
|
|
51
|
+
classNameMapBuilder: typeof mod.buildClassNameMap === "function" ? mod.buildClassNameMap : undefined,
|
|
52
|
+
libDeclGenerator: typeof mod.tryGenerateLibDecl === "function" ? mod.tryGenerateLibDecl : undefined,
|
|
53
|
+
};
|
|
54
|
+
setLoadedFramework(framework);
|
|
55
|
+
registerPlatformStrategy(strategy);
|
|
56
|
+
}
|
|
57
|
+
return mod;
|
|
58
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PlatformStrategy } from "./api/shared/index.js";
|
|
2
|
+
import type { CompileResult, UploadResult, ToolchainOptions } from "./api/shared/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Components loaded from a framework package.
|
|
5
|
+
*/
|
|
6
|
+
export interface LoadedFramework {
|
|
7
|
+
/** The platform strategy (e.g. ArduinoStrategy, NativeAVRStrategy) */
|
|
8
|
+
strategy: PlatformStrategy;
|
|
9
|
+
/** Optional toolchain for compile/upload/monitor (framework-specific) */
|
|
10
|
+
toolchain?: FrameworkToolchain;
|
|
11
|
+
/** Framework library import resolution (e.g., Arduino library detection) */
|
|
12
|
+
libraryResolver?: FrameworkLibraryResolver;
|
|
13
|
+
/** Framework class name mapping for library imports */
|
|
14
|
+
classNameMapBuilder?: (imports: any[]) => Map<string, string>;
|
|
15
|
+
/** Framework library .d.ts declaration generation */
|
|
16
|
+
libDeclGenerator?: (modulePath: string, file: string) => string | undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolves framework-specific library imports (e.g., Arduino libraries).
|
|
20
|
+
*/
|
|
21
|
+
export interface FrameworkLibraryResolver {
|
|
22
|
+
isFrameworkLibraryImport(moduleSpecifier: string): boolean;
|
|
23
|
+
getFrameworkLibraryHeaderName(moduleSpecifier: string): string | undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Toolchain operations that a framework package may provide.
|
|
27
|
+
* Uses a generic options bag so each framework reads what it needs
|
|
28
|
+
* and ignores the rest.
|
|
29
|
+
*/
|
|
30
|
+
export interface FrameworkToolchain {
|
|
31
|
+
prepare?(outputDir: string, entryPoint: string): void;
|
|
32
|
+
compile(options: ToolchainOptions): CompileResult;
|
|
33
|
+
upload?(options: ToolchainOptions): UploadResult;
|
|
34
|
+
monitor?(options: ToolchainOptions): void;
|
|
35
|
+
}
|
|
36
|
+
export declare function setLoadedFramework(framework: LoadedFramework): void;
|
|
37
|
+
export declare function getLoadedFramework(): LoadedFramework;
|
|
38
|
+
export declare function hasLoadedFramework(): boolean;
|
|
39
|
+
export declare function clearLoadedFramework(): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Framework Registry
|
|
3
|
+
//
|
|
4
|
+
// Holds the dynamically loaded framework package components so that CLI
|
|
5
|
+
// modules can access framework-specific strategy and toolchain without
|
|
6
|
+
// static import coupling.
|
|
7
|
+
//
|
|
8
|
+
// Replaces the former FrameworkApi singleton (CP5 decoupling). After moving
|
|
9
|
+
// polyfills, snprintf, and debug codegen into the CLI (CP1-CP3), the only
|
|
10
|
+
// remaining framework services are the strategy and toolchain.
|
|
11
|
+
//
|
|
12
|
+
// The registry is populated once per transpilation and cleared between runs.
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// ── Singleton state ────────────────────────────────────────────────────────
|
|
15
|
+
let _framework;
|
|
16
|
+
export function setLoadedFramework(framework) {
|
|
17
|
+
_framework = framework;
|
|
18
|
+
}
|
|
19
|
+
export function getLoadedFramework() {
|
|
20
|
+
if (!_framework) {
|
|
21
|
+
throw new Error("Framework not loaded. Ensure a framework package is loaded before transpilation.");
|
|
22
|
+
}
|
|
23
|
+
return _framework;
|
|
24
|
+
}
|
|
25
|
+
export function hasLoadedFramework() {
|
|
26
|
+
return _framework !== undefined;
|
|
27
|
+
}
|
|
28
|
+
export function clearLoadedFramework() {
|
|
29
|
+
_framework = undefined;
|
|
30
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental transpilation cache for persistent file change detection.
|
|
3
|
+
*
|
|
4
|
+
* NOTE: This module is currently UNUSED. The transpile pipeline does not import
|
|
5
|
+
* it because incremental builds were unsound: the pipeline wiped the cache and
|
|
6
|
+
* the output directory before loading, and even on a partial rebuild it built
|
|
7
|
+
* raw IR only for changed files, so cross-module metadata (enums, class field
|
|
8
|
+
* types, accessors, function return types) was incomplete for unchanged graph
|
|
9
|
+
* files. Re-enabling incremental builds safely requires rehydrating cached
|
|
10
|
+
* IR/metadata for EVERY file in the graph before the aggregation passes in
|
|
11
|
+
* transpile.ts, not just the changed ones.
|
|
12
|
+
*
|
|
13
|
+
* This module enables incremental builds by:
|
|
14
|
+
* 1. Tracking file content hashes across sessions
|
|
15
|
+
* 2. Detecting which files have changed
|
|
16
|
+
* 3. Building dependency graphs to identify transitive changes
|
|
17
|
+
* 4. Caching transpilation results for unchanged files
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Result of checking if a file needs retranspilation
|
|
21
|
+
*/
|
|
22
|
+
interface FileChangeStatus {
|
|
23
|
+
filePath: string;
|
|
24
|
+
/** Whether the file needs retranspilation */
|
|
25
|
+
needsRetranspile: boolean;
|
|
26
|
+
/** Reason for retranspilation */
|
|
27
|
+
reason: "changed" | "new" | "dependency-changed" | "cache-miss" | "output-missing" | "none";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Options for incremental cache
|
|
31
|
+
*/
|
|
32
|
+
interface IncrementalCacheOptions {
|
|
33
|
+
/** Path to the cache file (default: .cuttlefish-cache.json in project root) */
|
|
34
|
+
cachePath?: string;
|
|
35
|
+
/** Project root directory */
|
|
36
|
+
rootDir: string;
|
|
37
|
+
/** Whether to enable incremental builds (default: true) */
|
|
38
|
+
enabled?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Incremental transpilation cache manager
|
|
42
|
+
*/
|
|
43
|
+
export declare class IncrementalCache {
|
|
44
|
+
private cachePath;
|
|
45
|
+
private rootDir;
|
|
46
|
+
private enabled;
|
|
47
|
+
private cache;
|
|
48
|
+
private dirty;
|
|
49
|
+
constructor(options: IncrementalCacheOptions);
|
|
50
|
+
/**
|
|
51
|
+
* Load cache from disk, or create empty cache
|
|
52
|
+
*/
|
|
53
|
+
private load;
|
|
54
|
+
/**
|
|
55
|
+
* Create an empty cache structure
|
|
56
|
+
*/
|
|
57
|
+
private createEmptyCache;
|
|
58
|
+
/**
|
|
59
|
+
* Save cache to disk (if dirty)
|
|
60
|
+
*/
|
|
61
|
+
save(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Check if a file has changed since last cache
|
|
64
|
+
*/
|
|
65
|
+
hasFileChanged(filePath: string): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Check if a file's outputs still exist
|
|
68
|
+
*/
|
|
69
|
+
outputsExist(filePath: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Get files that need retranspilation based on changes
|
|
72
|
+
*/
|
|
73
|
+
getFilesNeedingRetranspile(filePaths: string[]): FileChangeStatus[];
|
|
74
|
+
/**
|
|
75
|
+
* Update cache entry for a file
|
|
76
|
+
*/
|
|
77
|
+
updateFile(filePath: string, content: string, dependencies: string[], outputs: string[]): void;
|
|
78
|
+
/**
|
|
79
|
+
* Remove a file from the cache
|
|
80
|
+
*/
|
|
81
|
+
removeFile(filePath: string): void;
|
|
82
|
+
/**
|
|
83
|
+
* Get cached outputs for a file (if valid)
|
|
84
|
+
*/
|
|
85
|
+
getCachedOutputs(filePath: string): string[] | null;
|
|
86
|
+
/**
|
|
87
|
+
* Clear the entire cache
|
|
88
|
+
*/
|
|
89
|
+
clear(): void;
|
|
90
|
+
/**
|
|
91
|
+
* Get cache statistics
|
|
92
|
+
*/
|
|
93
|
+
getStats(): {
|
|
94
|
+
fileCount: number;
|
|
95
|
+
cachePath: string;
|
|
96
|
+
createdAt: number;
|
|
97
|
+
updatedAt: number;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Check if incremental caching is enabled
|
|
101
|
+
*/
|
|
102
|
+
isEnabled(): boolean;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Initialize the global incremental cache
|
|
106
|
+
*/
|
|
107
|
+
export declare function initIncrementalCache(options: IncrementalCacheOptions): IncrementalCache;
|
|
108
|
+
/**
|
|
109
|
+
* Get the global incremental cache (must be initialized first)
|
|
110
|
+
*/
|
|
111
|
+
export declare function getIncrementalCache(): IncrementalCache | null;
|
|
112
|
+
/**
|
|
113
|
+
* Save and clear the global incremental cache
|
|
114
|
+
*/
|
|
115
|
+
export declare function saveAndClearIncrementalCache(): void;
|
|
116
|
+
export {};
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental transpilation cache for persistent file change detection.
|
|
3
|
+
*
|
|
4
|
+
* NOTE: This module is currently UNUSED. The transpile pipeline does not import
|
|
5
|
+
* it because incremental builds were unsound: the pipeline wiped the cache and
|
|
6
|
+
* the output directory before loading, and even on a partial rebuild it built
|
|
7
|
+
* raw IR only for changed files, so cross-module metadata (enums, class field
|
|
8
|
+
* types, accessors, function return types) was incomplete for unchanged graph
|
|
9
|
+
* files. Re-enabling incremental builds safely requires rehydrating cached
|
|
10
|
+
* IR/metadata for EVERY file in the graph before the aggregation passes in
|
|
11
|
+
* transpile.ts, not just the changed ones.
|
|
12
|
+
*
|
|
13
|
+
* This module enables incremental builds by:
|
|
14
|
+
* 1. Tracking file content hashes across sessions
|
|
15
|
+
* 2. Detecting which files have changed
|
|
16
|
+
* 3. Building dependency graphs to identify transitive changes
|
|
17
|
+
* 4. Caching transpilation results for unchanged files
|
|
18
|
+
*/
|
|
19
|
+
import fs from "node:fs";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import crypto from "node:crypto";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
/**
|
|
25
|
+
* Cache file version - increment when format changes
|
|
26
|
+
*/
|
|
27
|
+
const CACHE_VERSION = 1;
|
|
28
|
+
function computeToolchainFingerprint() {
|
|
29
|
+
const candidates = [
|
|
30
|
+
path.join(__dirname, "transpile.js"),
|
|
31
|
+
path.join(__dirname, "transpile.ts"),
|
|
32
|
+
path.join(__dirname, "emit", "cpp-emitter.js"),
|
|
33
|
+
path.join(__dirname, "emit", "cpp-emitter.ts"),
|
|
34
|
+
path.join(__dirname, "ir", "build-ir.js"),
|
|
35
|
+
path.join(__dirname, "ir", "build-ir.ts"),
|
|
36
|
+
path.join(__dirname, "ir", "ownership-analysis.js"),
|
|
37
|
+
path.join(__dirname, "ir", "ownership-analysis.ts"),
|
|
38
|
+
path.join(__dirname, "ir", "validation-orchestrator.js"),
|
|
39
|
+
path.join(__dirname, "ir", "validation-orchestrator.ts"),
|
|
40
|
+
];
|
|
41
|
+
const signature = candidates
|
|
42
|
+
.filter((filePath) => fs.existsSync(filePath))
|
|
43
|
+
.map((filePath) => {
|
|
44
|
+
const stat = fs.statSync(filePath);
|
|
45
|
+
return `${path.basename(filePath)}:${stat.size}:${stat.mtimeMs}`;
|
|
46
|
+
})
|
|
47
|
+
.join("|");
|
|
48
|
+
return crypto.createHash("sha256").update(signature).digest("hex").slice(0, 16);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Compute a hash of file content
|
|
52
|
+
*/
|
|
53
|
+
function computeFileHash(content) {
|
|
54
|
+
return crypto.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Default cache file name
|
|
58
|
+
*/
|
|
59
|
+
const DEFAULT_CACHE_NAME = ".cuttlefish-cache.json";
|
|
60
|
+
/**
|
|
61
|
+
* Incremental transpilation cache manager
|
|
62
|
+
*/
|
|
63
|
+
export class IncrementalCache {
|
|
64
|
+
constructor(options) {
|
|
65
|
+
this.dirty = false;
|
|
66
|
+
this.rootDir = path.resolve(options.rootDir);
|
|
67
|
+
this.cachePath = options.cachePath ?? path.join(this.rootDir, DEFAULT_CACHE_NAME);
|
|
68
|
+
this.enabled = options.enabled ?? true;
|
|
69
|
+
this.cache = this.load();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Load cache from disk, or create empty cache
|
|
73
|
+
*/
|
|
74
|
+
load() {
|
|
75
|
+
if (!this.enabled) {
|
|
76
|
+
return this.createEmptyCache();
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
if (fs.existsSync(this.cachePath)) {
|
|
80
|
+
const content = fs.readFileSync(this.cachePath, "utf8");
|
|
81
|
+
const data = JSON.parse(content);
|
|
82
|
+
const currentToolchainFingerprint = computeToolchainFingerprint();
|
|
83
|
+
// Validate cache version and root
|
|
84
|
+
if (data.version === CACHE_VERSION &&
|
|
85
|
+
data.toolchainFingerprint === currentToolchainFingerprint &&
|
|
86
|
+
path.resolve(data.rootDir) === this.rootDir) {
|
|
87
|
+
return data;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
if (process.env.CUTTLEFISH_DEBUG)
|
|
93
|
+
console.error("[incremental-cache] Corrupted cache file:", error);
|
|
94
|
+
}
|
|
95
|
+
return this.createEmptyCache();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Create an empty cache structure
|
|
99
|
+
*/
|
|
100
|
+
createEmptyCache() {
|
|
101
|
+
return {
|
|
102
|
+
version: CACHE_VERSION,
|
|
103
|
+
toolchainFingerprint: computeToolchainFingerprint(),
|
|
104
|
+
rootDir: this.rootDir,
|
|
105
|
+
files: {},
|
|
106
|
+
createdAt: Date.now(),
|
|
107
|
+
updatedAt: Date.now(),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Save cache to disk (if dirty)
|
|
112
|
+
*/
|
|
113
|
+
save() {
|
|
114
|
+
if (!this.enabled || !this.dirty) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this.cache.updatedAt = Date.now();
|
|
118
|
+
try {
|
|
119
|
+
// Ensure directory exists
|
|
120
|
+
const dir = path.dirname(this.cachePath);
|
|
121
|
+
if (!fs.existsSync(dir)) {
|
|
122
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
123
|
+
}
|
|
124
|
+
fs.writeFileSync(this.cachePath, JSON.stringify(this.cache, null, 2), "utf8");
|
|
125
|
+
this.dirty = false;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (process.env.CUTTLEFISH_DEBUG)
|
|
129
|
+
console.error("[incremental-cache] Failed to save cache:", error);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if a file has changed since last cache
|
|
134
|
+
*/
|
|
135
|
+
hasFileChanged(filePath) {
|
|
136
|
+
const resolved = path.resolve(filePath);
|
|
137
|
+
const entry = this.cache.files[resolved];
|
|
138
|
+
if (!entry) {
|
|
139
|
+
return true; // New file
|
|
140
|
+
}
|
|
141
|
+
// Quick check: mtime and size
|
|
142
|
+
try {
|
|
143
|
+
const stat = fs.statSync(resolved);
|
|
144
|
+
if (stat.mtimeMs !== entry.mtime || stat.size !== entry.size) {
|
|
145
|
+
// Content might have changed, verify with hash
|
|
146
|
+
const content = fs.readFileSync(resolved, "utf8");
|
|
147
|
+
const hash = computeFileHash(content);
|
|
148
|
+
return hash !== entry.hash;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return true; // File doesn't exist or error
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Check if a file's outputs still exist
|
|
158
|
+
*/
|
|
159
|
+
outputsExist(filePath) {
|
|
160
|
+
const resolved = path.resolve(filePath);
|
|
161
|
+
const entry = this.cache.files[resolved];
|
|
162
|
+
if (!entry || !entry.outputs.length) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
return entry.outputs.every((output) => fs.existsSync(output));
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get files that need retranspilation based on changes
|
|
169
|
+
*/
|
|
170
|
+
getFilesNeedingRetranspile(filePaths) {
|
|
171
|
+
const results = [];
|
|
172
|
+
const changedFiles = new Set();
|
|
173
|
+
const dependents = new Set();
|
|
174
|
+
// First pass: identify directly changed files
|
|
175
|
+
for (const filePath of filePaths) {
|
|
176
|
+
const resolved = path.resolve(filePath);
|
|
177
|
+
const entry = this.cache.files[resolved];
|
|
178
|
+
if (!entry) {
|
|
179
|
+
changedFiles.add(resolved);
|
|
180
|
+
results.push({
|
|
181
|
+
filePath: resolved,
|
|
182
|
+
needsRetranspile: true,
|
|
183
|
+
reason: "new",
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
else if (this.hasFileChanged(resolved)) {
|
|
187
|
+
changedFiles.add(resolved);
|
|
188
|
+
results.push({
|
|
189
|
+
filePath: resolved,
|
|
190
|
+
needsRetranspile: true,
|
|
191
|
+
reason: "changed",
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
else if (!this.outputsExist(resolved)) {
|
|
195
|
+
changedFiles.add(resolved);
|
|
196
|
+
results.push({
|
|
197
|
+
filePath: resolved,
|
|
198
|
+
needsRetranspile: true,
|
|
199
|
+
reason: "output-missing",
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
results.push({
|
|
204
|
+
filePath: resolved,
|
|
205
|
+
needsRetranspile: false,
|
|
206
|
+
reason: "none",
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Build reverse dependency map (who depends on whom)
|
|
211
|
+
const reverseDeps = new Map();
|
|
212
|
+
for (const [filePath, entry] of Object.entries(this.cache.files)) {
|
|
213
|
+
for (const dep of entry.dependencies) {
|
|
214
|
+
if (!reverseDeps.has(dep)) {
|
|
215
|
+
reverseDeps.set(dep, new Set());
|
|
216
|
+
}
|
|
217
|
+
reverseDeps.get(dep).add(filePath);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Second pass: find transitive dependents of changed files
|
|
221
|
+
const toProcess = [...changedFiles];
|
|
222
|
+
while (toProcess.length > 0) {
|
|
223
|
+
const changed = toProcess.pop();
|
|
224
|
+
const dependentsOfChanged = reverseDeps.get(changed);
|
|
225
|
+
if (dependentsOfChanged) {
|
|
226
|
+
for (const dependent of dependentsOfChanged) {
|
|
227
|
+
if (!changedFiles.has(dependent) && filePaths.includes(dependent)) {
|
|
228
|
+
dependents.add(dependent);
|
|
229
|
+
toProcess.push(dependent);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Update results for dependents
|
|
235
|
+
for (const result of results) {
|
|
236
|
+
if (dependents.has(result.filePath)) {
|
|
237
|
+
result.needsRetranspile = true;
|
|
238
|
+
result.reason = "dependency-changed";
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return results;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Update cache entry for a file
|
|
245
|
+
*/
|
|
246
|
+
updateFile(filePath, content, dependencies, outputs) {
|
|
247
|
+
const resolved = path.resolve(filePath);
|
|
248
|
+
try {
|
|
249
|
+
const stat = fs.statSync(resolved);
|
|
250
|
+
const hash = computeFileHash(content);
|
|
251
|
+
this.cache.files[resolved] = {
|
|
252
|
+
hash,
|
|
253
|
+
mtime: stat.mtimeMs,
|
|
254
|
+
size: stat.size,
|
|
255
|
+
dependencies: dependencies.map((d) => path.resolve(d)),
|
|
256
|
+
outputs: outputs.map((o) => path.resolve(o)),
|
|
257
|
+
};
|
|
258
|
+
this.dirty = true;
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
// File doesn't exist, skip caching
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Remove a file from the cache
|
|
266
|
+
*/
|
|
267
|
+
removeFile(filePath) {
|
|
268
|
+
const resolved = path.resolve(filePath);
|
|
269
|
+
if (this.cache.files[resolved]) {
|
|
270
|
+
delete this.cache.files[resolved];
|
|
271
|
+
this.dirty = true;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Get cached outputs for a file (if valid)
|
|
276
|
+
*/
|
|
277
|
+
getCachedOutputs(filePath) {
|
|
278
|
+
const resolved = path.resolve(filePath);
|
|
279
|
+
const entry = this.cache.files[resolved];
|
|
280
|
+
if (!entry || this.hasFileChanged(resolved) || !this.outputsExist(resolved)) {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
return entry.outputs;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Clear the entire cache
|
|
287
|
+
*/
|
|
288
|
+
clear() {
|
|
289
|
+
this.cache = this.createEmptyCache();
|
|
290
|
+
this.dirty = true;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Get cache statistics
|
|
294
|
+
*/
|
|
295
|
+
getStats() {
|
|
296
|
+
return {
|
|
297
|
+
fileCount: Object.keys(this.cache.files).length,
|
|
298
|
+
cachePath: this.cachePath,
|
|
299
|
+
createdAt: this.cache.createdAt,
|
|
300
|
+
updatedAt: this.cache.updatedAt,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Check if incremental caching is enabled
|
|
305
|
+
*/
|
|
306
|
+
isEnabled() {
|
|
307
|
+
return this.enabled;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Global incremental cache instance (lazy-initialized)
|
|
312
|
+
*/
|
|
313
|
+
let globalCache = null;
|
|
314
|
+
/**
|
|
315
|
+
* Initialize the global incremental cache
|
|
316
|
+
*/
|
|
317
|
+
export function initIncrementalCache(options) {
|
|
318
|
+
globalCache = new IncrementalCache(options);
|
|
319
|
+
return globalCache;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Get the global incremental cache (must be initialized first)
|
|
323
|
+
*/
|
|
324
|
+
export function getIncrementalCache() {
|
|
325
|
+
return globalCache;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Save and clear the global incremental cache
|
|
329
|
+
*/
|
|
330
|
+
export function saveAndClearIncrementalCache() {
|
|
331
|
+
if (globalCache) {
|
|
332
|
+
globalCache.save();
|
|
333
|
+
globalCache = null;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProgramIR } from '../api/index.js';
|
|
2
|
+
import type { BoardConstants } from '../api/shared/index.js';
|
|
3
|
+
import type { Diagnostic } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Validate ADC range comparisons in a program.
|
|
6
|
+
*
|
|
7
|
+
* @param program - The program IR to validate
|
|
8
|
+
* @param boardConstants - Board constants containing ADC resolution
|
|
9
|
+
* @returns Array of diagnostics for ADC range issues
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateADCRange(program: ProgramIR, boardConstants: BoardConstants | undefined): Diagnostic[];
|