@contember/bindx-react 0.1.56 → 0.1.59

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.
Files changed (44) hide show
  1. package/dist/hooks/useRootSelection.d.ts +22 -0
  2. package/dist/hooks/useRootSelection.d.ts.map +1 -0
  3. package/dist/index.d.ts +3 -3
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/jsx/analyzer.d.ts +5 -0
  6. package/dist/jsx/analyzer.d.ts.map +1 -1
  7. package/dist/jsx/collectionHelpers.d.ts +20 -0
  8. package/dist/jsx/collectionHelpers.d.ts.map +1 -0
  9. package/dist/jsx/collectorContract.d.ts +25 -0
  10. package/dist/jsx/collectorContract.d.ts.map +1 -0
  11. package/dist/jsx/compiledSelection.d.ts +80 -0
  12. package/dist/jsx/compiledSelection.d.ts.map +1 -0
  13. package/dist/jsx/compiledSelectionShape.d.ts +12 -0
  14. package/dist/jsx/compiledSelectionShape.d.ts.map +1 -0
  15. package/dist/jsx/componentBuilder.d.ts +5 -2
  16. package/dist/jsx/componentBuilder.d.ts.map +1 -1
  17. package/dist/jsx/componentBuilder.types.d.ts +32 -1
  18. package/dist/jsx/componentBuilder.types.d.ts.map +1 -1
  19. package/dist/jsx/componentFactory.d.ts +22 -2
  20. package/dist/jsx/componentFactory.d.ts.map +1 -1
  21. package/dist/jsx/components/Entity.d.ts +7 -0
  22. package/dist/jsx/components/Entity.d.ts.map +1 -1
  23. package/dist/jsx/index.d.ts +4 -0
  24. package/dist/jsx/index.d.ts.map +1 -1
  25. package/dist/jsx/proxyShared.d.ts +8 -0
  26. package/dist/jsx/proxyShared.d.ts.map +1 -1
  27. package/dist/jsx/withCollector.d.ts +7 -8
  28. package/dist/jsx/withCollector.d.ts.map +1 -1
  29. package/package.json +3 -3
  30. package/src/hooks/useRootSelection.ts +111 -0
  31. package/src/index.ts +13 -0
  32. package/src/jsx/analyzer.ts +10 -2
  33. package/src/jsx/collectionHelpers.ts +55 -0
  34. package/src/jsx/collectorContract.tsx +71 -0
  35. package/src/jsx/collectorProxy.ts +7 -1
  36. package/src/jsx/compiledSelection.ts +353 -0
  37. package/src/jsx/compiledSelectionShape.ts +86 -0
  38. package/src/jsx/componentBuilder.ts +28 -1
  39. package/src/jsx/componentBuilder.types.ts +38 -1
  40. package/src/jsx/componentFactory.ts +212 -42
  41. package/src/jsx/components/Entity.tsx +27 -8
  42. package/src/jsx/index.ts +18 -0
  43. package/src/jsx/proxyShared.ts +14 -0
  44. package/src/jsx/withCollector.ts +25 -10
package/src/jsx/index.ts CHANGED
@@ -101,9 +101,27 @@ export {
101
101
  // Standalone createComponent function
102
102
  export { createComponent } from './standaloneCreateComponent.js'
103
103
 
104
+ // Static (precompiled) selection validate-mode toggle
105
+ export { setStaticSelectionValidation } from './componentFactory.js'
106
+
107
+ // Compiled-selections killswitch — disable compiled literals at runtime without a rebuild
108
+ export { setCompiledSelectionsEnabled } from './componentFactory.js'
109
+
110
+ // Compiled selection contract (v2) — emitted by the selection compiler
111
+ export type { CompiledSelection, CompiledHole } from './compiledSelection.js'
112
+
104
113
  // withCollector — attach staticRender to a component for selection collection
105
114
  export { withCollector } from './withCollector.js'
106
115
 
116
+ // Declarative collector contracts — an alternative to a hand-written staticRender
117
+ export {
118
+ COLLECTOR_CONTRACT,
119
+ itemOf,
120
+ entityOf,
121
+ type CallbackContract,
122
+ type CollectorContract,
123
+ } from './collectorContract.js'
124
+
107
125
  export type {
108
126
  SelectionPropMeta,
109
127
  BindxComponentBase,
@@ -16,6 +16,15 @@ export const ENTITY_ACCESSOR_PROPERTIES = new Set([
16
16
  '__entityType', '__entityName', '__schema',
17
17
  ])
18
18
 
19
+ /**
20
+ * String keys React probes on any object it treats as a JSX child: `$$typeof`
21
+ * (isValidElement) and the `@@iterator` fallback (getIteratorFn). A collector
22
+ * proxy must return undefined for these — delegating to field access would
23
+ * upgrade a scalar to a bogus relation. Symbol probes (Symbol.iterator, …) pass
24
+ * through the symbol branch already.
25
+ */
26
+ export const REACT_ELEMENT_PROBE_KEYS = new Set(['$$typeof', '@@iterator'])
27
+
19
28
  /**
20
29
  * Wraps an object with $fields in a Proxy that supports direct field access.
21
30
  * - `entity.fieldName` is equivalent to `entity.$fields.fieldName`
@@ -29,6 +38,11 @@ export function wrapEntityRefWithFieldAccessProxy<T>(ref: { $fields: EntityField
29
38
  return Reflect.get(target, prop)
30
39
  }
31
40
 
41
+ // React element probes must not be captured as fields
42
+ if (REACT_ELEMENT_PROBE_KEYS.has(prop)) {
43
+ return Reflect.get(target, prop)
44
+ }
45
+
32
46
  // Known accessor properties - pass through
33
47
  if (ENTITY_ACCESSOR_PROPERTIES.has(prop)) {
34
48
  return Reflect.get(target, prop)
@@ -1,4 +1,6 @@
1
1
  import type { ReactNode } from 'react'
2
+ import type { CollectorContract } from './collectorContract.js'
3
+ import { COLLECTOR_CONTRACT, deriveContractStaticRender } from './collectorContract.js'
2
4
 
3
5
  /**
4
6
  * Attaches a static render function to a component for selection collection.
@@ -25,21 +27,34 @@ import type { ReactNode } from 'react'
25
27
  * )
26
28
  * )
27
29
  *
28
- * // Programmatic field access (no JSX needed)
29
- * export const Uploader = withCollector(
30
- * function Uploader({ field, fileType }) { ... },
31
- * (props) => {
32
- * const entity = props.field.$entity
33
- * for (const ext of props.fileType.extractors) entity[ext.fieldName]
34
- * return null
35
- * }
30
+ * // Declarative contract instead of a hand-written staticRender: `children` is invoked
31
+ * // per item of the `field` has-many relation. The staticRender is derived automatically.
32
+ * export const ItemRepeater = withCollector(
33
+ * function ItemRepeater({ field, children, ... }) { ... },
34
+ * { children: itemOf('field') }
36
35
  * )
37
36
  * ```
38
37
  */
39
38
  export function withCollector<TComponent extends (...args: never[]) => ReactNode>(
40
39
  component: TComponent,
41
40
  staticRender: (props: Parameters<TComponent>[0]) => ReactNode,
41
+ ): TComponent
42
+ export function withCollector<TComponent extends (...args: never[]) => ReactNode>(
43
+ component: TComponent,
44
+ contract: CollectorContract,
45
+ ): TComponent
46
+ export function withCollector<TComponent extends (...args: never[]) => ReactNode>(
47
+ component: TComponent,
48
+ contractOrStaticRender: ((props: Parameters<TComponent>[0]) => ReactNode) | CollectorContract,
42
49
  ): TComponent {
43
- (component as TComponent & { staticRender: typeof staticRender }).staticRender = staticRender
44
- return component
50
+ // A function is a staticRender; a plain object is a declarative contract.
51
+ if (typeof contractOrStaticRender === 'function') {
52
+ return Object.assign(component, { staticRender: contractOrStaticRender })
53
+ }
54
+
55
+ const contract = contractOrStaticRender
56
+ return Object.assign(component, {
57
+ staticRender: deriveContractStaticRender(contract),
58
+ [COLLECTOR_CONTRACT]: contract,
59
+ })
45
60
  }