@geastack/core 0.1.28 → 0.1.30

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geastack/core",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "GeaStack app API, reactivity headers, runtime sources, and type declarations.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -62,9 +62,10 @@
62
62
  "@babel/types": "^7.23.0",
63
63
  "@geajs/core": "1.5.1",
64
64
  "@geajs/vite-plugin": "1.5.0",
65
- "@geastack/compiler": "^1.0.15",
66
- "@geastack/geatsc-plugin-gea": "^0.1.8",
65
+ "@geastack/compiler": "^1.0.19",
66
+ "@geastack/geatsc-plugin-gea": "^0.1.11",
67
67
  "opentype.js": "^2.0.0",
68
68
  "vite": "^8.0.0"
69
- }
69
+ },
70
+ "gitHead": "d118359147092ff5e0d319c892aa11c59fab03bc"
70
71
  }
package/runtime.cpp CHANGED
@@ -363,6 +363,16 @@ bool Runtime::boot(const RuntimeOptions &options)
363
363
  // correctly in PSRAM the whole time. Display::init() now claims its floor
364
364
  // before this line, and this bring-up shrinks it the designed way.
365
365
  services::DiagnosticsServer::print("Starting WiFi after display init\n");
366
+ // This synchronous boot path bypasses WifiStation::ensureBringUp(),
367
+ // which normally yields display staging before allocating the radio.
368
+ // No frame task is running yet, so apply the reservation here rather
369
+ // than waiting for a frame that cannot run until init() returns.
370
+ // Keep the already-secured minimum pipeline, yielding the rest before
371
+ // both radio and application audio allocations. A fixed 56 KiB shrink
372
+ // left a 52 KiB staging pool on this boot path and starved I2S DMA.
373
+ gea::platform::display::Display::reserveInternal(
374
+ static_cast<std::size_t>(gea::platform::display::Display::flushBufferBytes()));
375
+ gea::platform::display::Display::applyPendingInternalReserve();
366
376
  network::wifi().init();
367
377
  }
368
378
  #endif
@@ -406,6 +416,14 @@ bool Runtime::boot(const RuntimeOptions &options)
406
416
  services::HeapProbe::log("runtime:after_frame_start");
407
417
  services::StackProbe::logCurrentTask("runtime:after_frame_start");
408
418
  services::HeapTaskSummary::log("runtime:after_frame_start");
419
+ #if GEA_EMBEDDED_WIFI_EARLY_CONNECT
420
+ // The early-connect loan protects radio, app, and task initialization.
421
+ // They now own their allocations; let the frame task grow staging into
422
+ // the remaining heap instead of retaining the two-row boot floor forever.
423
+ // Allocation still observes the DMA reserve and falls back when RAM is tight.
424
+ if (GEA_EMBEDDED_WIFI_SSID[0] != '\0')
425
+ gea::platform::display::Display::reserveInternal(0);
426
+ #endif
409
427
  services::RuntimeLog::appStarted(networkReady);
410
428
  #endif
411
429
 
@@ -6,8 +6,9 @@ import { spawnSync } from 'node:child_process'
6
6
  import { createRequire } from 'node:module'
7
7
  import { fileURLToPath, pathToFileURL } from 'node:url'
8
8
  import { inlineJsonImports, transformGeaEmbeddedCompatSource } from './gea-embedded-compat-transform.mjs'
9
- import { shouldIgnoreCompatStagingDirectory } from './gea-embedded-compat-staging.mjs'
9
+ import { normalizeEmbeddedJsxOptions, shouldIgnoreCompatStagingDirectory } from './gea-embedded-compat-staging.mjs'
10
10
  import { dotEnvDefines, inlineProcessEnv } from './dotenv-defines.mjs'
11
+ import { resolveCompilerRuntimeEntry } from './gea-native-style-plugin.mjs'
11
12
  import {
12
13
  MODULE_HINT_SCOPE,
13
14
  applyBundledTypeHints,
@@ -360,6 +361,7 @@ function stateRuntimeAliasToTypeScript(stagedAppDir, compatSrcDir, stagingRoot)
360
361
  }
361
362
  }
362
363
  const options = config.compilerOptions ?? (config.compilerOptions = {})
364
+ normalizeEmbeddedJsxOptions(options)
363
365
  options.baseUrl = options.baseUrl ?? '.'
364
366
  const base = path.resolve(stagedAppDir, options.baseUrl)
365
367
  // Both specifiers, because the Vite config aliases both to the same
@@ -458,23 +460,8 @@ function writeCompatViteConfig({ configPath, compatSrcDir, appDir, entry, viteOu
458
460
  // whole reactive runtime dynamically (gea_cpp_value, ill-formed auto-vectors,
459
461
  // proxy derefs). From source, everything is typed and lowers natively, exactly
460
462
  // like three.js/hono/mongodb. The env var still wins when explicitly set;
461
- // otherwise resolve the package's source entry via its node_modules symlink.
462
- let compilerRuntimeEntry = process.env.GEA_COMPILER_RUNTIME_SOURCE || ''
463
- if (!compilerRuntimeEntry) {
464
- for (const base of [appDir, coreRoot]) {
465
- try {
466
- const pkgDir = fs.realpathSync(path.join(base, 'node_modules/@geajs/core'))
467
- const srcIndex = path.join(pkgDir, 'src/index.ts')
468
- if (fs.existsSync(srcIndex) && fs.existsSync(path.join(pkgDir, 'src/compiler-runtime.ts'))) {
469
- compilerRuntimeEntry = srcIndex
470
- break
471
- }
472
- } catch {
473
- // No @geajs/core source under this base (e.g. published-only install) —
474
- // fall through; the alias stays empty and the dist runtime is used.
475
- }
476
- }
477
- }
463
+ // otherwise follow ordinary package resolution, including hoisted installs.
464
+ const compilerRuntimeEntry = process.env.GEA_COMPILER_RUNTIME_SOURCE || resolveCompilerRuntimeEntry([appDir, coreRoot])
478
465
  const compilerRuntimeAlias = compilerRuntimeEntry && fs.existsSync(compilerRuntimeEntry)
479
466
  ? ` { find: new RegExp('^@geajs/core$'), replacement: ${q(compilerRuntimeEntry)} },\n`
480
467
  : ''
@@ -4279,7 +4266,10 @@ const moduleGraphOutOption = readOption('--module-graph-out') ?? process.env.GEA
4279
4266
  const moduleGraphOnly = hasFlag('--module-graph-only')
4280
4267
  const moduleGraphCompileRequested = hasFlag('--compile-module-graph')
4281
4268
  const moduleGraphCompileDisabled = hasFlag('--no-compile-module-graph')
4282
- const geaPluginSpecifier = path.resolve(readOption('--geatsc-gea-plugin') ?? requireFromLib.resolve('@geastack/geatsc-plugin-gea'))
4269
+ const geaPluginSpecifier = path.resolve(
4270
+ readOption('--geatsc-gea-plugin') ??
4271
+ (process.env.GEA_PLUGIN_DIR ? path.join(process.env.GEA_PLUGIN_DIR, 'dist/index.js') : undefined) ??
4272
+ requireFromLib.resolve('@geastack/geatsc-plugin-gea'))
4283
4273
  const extraGeatscPlugins = readAllOptions('--extra-geatsc-plugin').map((plugin) => path.resolve(plugin))
4284
4274
  const appendJsFiles = readAllOptions('--append-js').map((file) => path.resolve(file))
4285
4275
  const entry = readOption('--entry') ?? 'index.tsx'
@@ -15,3 +15,11 @@ const ignoredDirectorySet = new Set(COMPAT_STAGING_IGNORED_DIRECTORIES)
15
15
  export function shouldIgnoreCompatStagingDirectory(name) {
16
16
  return ignoredDirectorySet.has(name)
17
17
  }
18
+
19
+ // The browser JSX runtime declares Element as `any`. Embedded components are
20
+ // lowered through @geastack/core's typed global JSX namespace instead. Match
21
+ // the Component/Store import conversion without altering custom JSX providers
22
+ // or the application's original web tsconfig.
23
+ export function normalizeEmbeddedJsxOptions(options) {
24
+ if (options.jsxImportSource === '@geajs/core') delete options.jsxImportSource
25
+ }
@@ -151,7 +151,7 @@ function normalizeRuntimeCoreImports(ast) {
151
151
  const movedSpecs = []
152
152
 
153
153
  for (const node of ast.program.body) {
154
- if (!t.isImportDeclaration(node) || node.source.value !== '@geastack/core') {
154
+ if (!t.isImportDeclaration(node) || !['@geastack/core', '@geajs/core'].includes(node.source.value)) {
155
155
  nextBody.push(node)
156
156
  continue
157
157
  }
@@ -213,7 +213,7 @@ function transformTopLevelStatement(stmt) {
213
213
  }
214
214
 
215
215
  export function transformGeaEmbeddedCompatSource(code, filename) {
216
- if ((!code.includes('<') || !code.includes('>')) && !code.includes('@geastack/core')) return code
216
+ if ((!code.includes('<') || !code.includes('>')) && !code.includes('@geastack/core') && !code.includes('@geajs/core')) return code
217
217
 
218
218
  const ast = parser.parse(code, {
219
219
  sourceType: 'module',
@@ -1,5 +1,23 @@
1
1
  import fs from 'node:fs'
2
2
  import path from 'node:path'
3
+ import { createRequire } from 'node:module'
4
+
5
+ // Follow Node's node_modules search chain, including hoisted workspace installs.
6
+ // package.json need not be exposed by the package's exports map.
7
+ export function resolveCompilerRuntimeEntry(bases) {
8
+ for (const base of bases) {
9
+ const require = createRequire(path.join(path.resolve(base), 'package.json'))
10
+ for (const modules of require.resolve.paths('@geajs/core') || []) {
11
+ const source = path.join(modules, '@geajs/core/src')
12
+ const entry = path.join(source, 'index.ts')
13
+ if (fs.existsSync(entry) && fs.existsSync(path.join(source, 'compiler-runtime.ts')))
14
+ return fs.realpathSync(entry)
15
+ // An installed package shadows ancestors, even if it lacks typed sources.
16
+ if (fs.existsSync(path.join(modules, '@geajs/core/package.json'))) break
17
+ }
18
+ }
19
+ return ''
20
+ }
3
21
 
4
22
  /** Native lengths are raw numbers; only an authored CSS unit may introduce scaling. */
5
23
  export function geaNativeStylePlugin({ runtimeEntry }) {