@softize/opus 12.8.0 → 12.8.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/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ Depois de qualquer bump, rode os gates (`typecheck` · `test` · `opus check` ·
7
7
  `opus copy --check` · `base copy check` · `manifest:check`) — eles apontam o que a
8
8
  mudança cobra do seu código.
9
9
 
10
+ ## 12.8.1 — 2026-09-02
11
+
12
+ Num monorepo pnpm em que o workspace do contrato e o da SPA resolvem cópias distintas do Opus
13
+ (peers diferentes), as colunas de dicionário zero-config do `ActionList` e o fallback de opções
14
+ do `ActionForm` não encontravam o dicionário: a meta que `t.dict` grava no schema vivia num
15
+ `WeakMap` por instância, invisível para a outra cópia. A meta anexada por `attachLogicalType`
16
+ agora viaja também como propriedade não enumerável do próprio schema, chaveada por
17
+ `Symbol.for('@softize/opus/logical-type')`, e `getLogicalType` a lê quando o `WeakMap` local não
18
+ conhece o objeto. Sem mudança de API.
19
+
10
20
  ## 12.8.0 — 2026-09-02
11
21
 
12
22
  A apresentação de um dicionário passa a ser declarada no próprio `t.dict`, e não inferida por
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softize/opus",
3
- "version": "12.8.0",
3
+ "version": "12.8.1",
4
4
  "description": "End-to-end action protocol for TypeScript. Single package with subpath exports (core + adapters).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -5,12 +5,21 @@
5
5
  * labels de dict lendo a meta que viaja no schema do contrato, e a fronteira SPA
6
6
  * (gate de arquitetura) só deixa a UI tocar ui/lib/core. O `@softize/opus/schema`
7
7
  * re-exporta — a API pública não muda; as factories `t.*` seguem no driver.
8
+ *
9
+ * A meta é guardada de duas formas: num `WeakMap` desta instância e numa propriedade
10
+ * não enumerável do próprio schema, chaveada por `Symbol.for`. A segunda é o que
11
+ * atravessa instâncias do pacote: num monorepo pnpm, o workspace do contrato e o da
12
+ * SPA podem resolver cópias distintas do Opus (peers diferentes), e um `WeakMap` de
13
+ * uma cópia é invisível para a outra — o schema, não; ele é o mesmo objeto.
8
14
  */
9
15
 
10
16
  import type { LogicalTypeMeta } from './types.ts'
11
17
 
12
18
  const META = new WeakMap<object, LogicalTypeMeta>()
13
19
 
20
+ /** Chave global da propriedade que carrega a meta no próprio schema. */
21
+ export const LOGICAL_TYPE_PROPERTY = Symbol.for('@softize/opus/logical-type')
22
+
14
23
  /**
15
24
  * Anexa metadata logical type a qualquer schema (objeto). Drivers usam
16
25
  * internamente; consumers usam pra registrar tipos lógicos customizados.
@@ -20,12 +29,27 @@ export function attachLogicalType<S extends object>(
20
29
  meta: LogicalTypeMeta,
21
30
  ): S {
22
31
  META.set(schema, meta)
32
+ // Objeto congelado ou selado fica só no WeakMap — a assinatura aceita "qualquer objeto".
33
+ if (Object.isExtensible(schema)) {
34
+ Object.defineProperty(schema, LOGICAL_TYPE_PROPERTY, {
35
+ value: meta,
36
+ enumerable: false,
37
+ configurable: true,
38
+ writable: true,
39
+ })
40
+ }
23
41
  return schema
24
42
  }
25
43
 
26
44
  /**
27
- * Lê a metadata logical type anexada. Retorna `undefined` se ausente.
45
+ * Lê a metadata logical type anexada, por esta instância ou por outra cópia do
46
+ * pacote que tenha anexado no mesmo objeto. Retorna `undefined` se ausente.
28
47
  */
29
48
  export function getLogicalType(schema: object): LogicalTypeMeta | undefined {
30
- return META.get(schema)
49
+ const own = META.get(schema)
50
+ if (own !== undefined) return own
51
+ const carried = (schema as { [LOGICAL_TYPE_PROPERTY]?: unknown })[LOGICAL_TYPE_PROPERTY]
52
+ return carried !== null && typeof carried === 'object' && 'logicalType' in carried
53
+ ? (carried as LogicalTypeMeta)
54
+ : undefined
31
55
  }