@fugood/bricks-project 2.25.0-beta.49 → 2.25.0-beta.50

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/compile/index.ts CHANGED
@@ -6,7 +6,7 @@ import omit from 'lodash/omit'
6
6
  import { parse as parseAST } from 'acorn'
7
7
  import type { ExportNamedDeclaration, FunctionDeclaration } from 'acorn'
8
8
  import escodegen from 'escodegen'
9
- import { makeId } from '../utils/id'
9
+ import { makeSeededId } from '../utils/id'
10
10
  import { generateCalulationMap } from './util'
11
11
  import { templateActionNameMap } from './action-name-map'
12
12
  import { templateEventPropsMap } from '../utils/event-props'
@@ -185,10 +185,17 @@ const compileEvents = (
185
185
 
186
186
  let handlerKey
187
187
  let handlerTemplateKey
188
- if (handler === 'system' || typeof handler === 'string') {
189
- if (handler.startsWith('SUBSPACE_')) handlerKey = handler
190
- else handlerKey = handler.toUpperCase()
191
- if (handlerKey === 'SYSTEM') handlerTemplateKey = 'SYSTEM'
188
+ if (typeof handler === 'string') {
189
+ // Only the literal 'system' handler is normalized to the SYSTEM template key.
190
+ // SubspaceID (SUBSPACE_*) and ItemBrickID handlers are kept verbatim: the runtime
191
+ // resolves them case-sensitively (see mapEventMapHandlersWithNewId), so uppercasing
192
+ // a mixed-case ItemBrickID would break handler-to-item event wiring.
193
+ if (handler === 'system') {
194
+ handlerKey = 'SYSTEM'
195
+ handlerTemplateKey = 'SYSTEM'
196
+ } else {
197
+ handlerKey = handler
198
+ }
192
199
  } else if (typeof handler === 'function') {
193
200
  let instance = handler()
194
201
  if (instance?.id) {
@@ -486,6 +493,7 @@ const preloadTypes = [
486
493
  'media-resource-audio',
487
494
  'media-resource-file',
488
495
  'lottie-file-uri',
496
+ 'rive-file-uri',
489
497
  'ggml-model-asset',
490
498
  'gguf-model-asset',
491
499
  'binary-asset',
@@ -755,7 +763,14 @@ export const compile = async (app: Application) => {
755
763
  // validation (root_canvas_id is required before the conditional
756
764
  // schema fix is published).
757
765
  if (subspace.module?.link) {
758
- const placeholderCanvasId = makeId('canvas')
766
+ // Seed the placeholder id from the (stable) subspace id. `makeId('canvas')` would take
767
+ // the count-fallback branch (a process-global counter that is never reset), so the
768
+ // placeholder id depended on how many prior count-fallback ids had been minted — making
769
+ // it differ between recompiles and breaking compile's byte-stable-output contract
770
+ // (phantom config-change ops). `makeSeededId` keeps no global state, so identical source
771
+ // recompiles to an identical id. (`makeId('canvas', alias)` would instead throw
772
+ // "Duplicate makeId alias" on the second compile in a long-lived process.)
773
+ const placeholderCanvasId = makeSeededId('canvas', `${subspaceId}:module-placeholder`)
759
774
  subspaceMap[subspaceId] = {
760
775
  title: subspace.title,
761
776
  description: subspace.description,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fugood/bricks-project",
3
- "version": "2.25.0-beta.49",
3
+ "version": "2.25.0-beta.50",
4
4
  "main": "index.ts",
5
5
  "scripts": {
6
6
  "typecheck": "tsc --noEmit",
@@ -11,7 +11,7 @@
11
11
  "@babel/parser": "7.28.5",
12
12
  "@babel/traverse": "7.28.5",
13
13
  "@babel/types": "7.28.5",
14
- "@fugood/bricks-cli": "^2.25.0-beta.49",
14
+ "@fugood/bricks-cli": "^2.25.0-beta.50",
15
15
  "@huggingface/gguf": "^0.3.2",
16
16
  "@iarna/toml": "^3.0.0",
17
17
  "@modelcontextprotocol/sdk": "^1.15.0",
package/package.json.bak CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fugood/bricks-ctor",
3
- "version": "2.25.0-beta.49",
3
+ "version": "2.25.0-beta.50",
4
4
  "main": "index.ts",
5
5
  "scripts": {
6
6
  "typecheck": "tsc --noEmit",
@@ -11,7 +11,7 @@
11
11
  "@babel/parser": "7.28.5",
12
12
  "@babel/traverse": "7.28.5",
13
13
  "@babel/types": "7.28.5",
14
- "@fugood/bricks-cli": "^2.25.0-beta.49",
14
+ "@fugood/bricks-cli": "^2.25.0-beta.50",
15
15
  "@huggingface/gguf": "^0.3.2",
16
16
  "@iarna/toml": "^3.0.0",
17
17
  "@modelcontextprotocol/sdk": "^1.15.0",
@@ -924,7 +924,20 @@ const editEntry = async (projectDir: string, input: any) =>
924
924
  for (const [pathValue, value] of Object.entries(input.set || {})) {
925
925
  await setPathValue(targetObject, pathValue, value, ctx)
926
926
  }
927
- for (const pathValue of input.unset || []) {
927
+ // Apply unset paths highest array-index first: unsetPathValue splices arrays
928
+ // in place, so removing a lower index would shift the higher indices down and
929
+ // a later unset would then hit the wrong element (or no-op). Sorting descending
930
+ // by the numeric indices in each path keeps same-array removals correct;
931
+ // object-key and distinct-array removals are order-independent.
932
+ const orderedUnset = [...(input.unset || [])].sort((a: string, b: string) => {
933
+ const ka = parsePath(a).map((token) => ('index' in token ? token.index : -1))
934
+ const kb = parsePath(b).map((token) => ('index' in token ? token.index : -1))
935
+ for (let i = 0; i < Math.min(ka.length, kb.length); i += 1) {
936
+ if (ka[i] !== kb[i]) return kb[i] - ka[i]
937
+ }
938
+ return kb.length - ka.length
939
+ })
940
+ for (const pathValue of orderedUnset) {
928
941
  unsetPathValue(targetObject, pathValue)
929
942
  }
930
943