@contember/bindx-react 0.1.0
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/dist/batching/QueryBatcher.d.ts +31 -0
- package/dist/batching/QueryBatcher.d.ts.map +1 -0
- package/dist/batching/index.d.ts +2 -0
- package/dist/batching/index.d.ts.map +1 -0
- package/dist/components/EntityScope.d.ts +28 -0
- package/dist/components/EntityScope.d.ts.map +1 -0
- package/dist/dataview/DataGrid.d.ts +45 -0
- package/dist/dataview/DataGrid.d.ts.map +1 -0
- package/dist/dataview/DataGridPagination.d.ts +24 -0
- package/dist/dataview/DataGridPagination.d.ts.map +1 -0
- package/dist/dataview/DataGridToolbar.d.ts +16 -0
- package/dist/dataview/DataGridToolbar.d.ts.map +1 -0
- package/dist/dataview/DataViewContext.d.ts +32 -0
- package/dist/dataview/DataViewContext.d.ts.map +1 -0
- package/dist/dataview/columns.d.ts +115 -0
- package/dist/dataview/columns.d.ts.map +1 -0
- package/dist/dataview/contextHooks.d.ts +48 -0
- package/dist/dataview/contextHooks.d.ts.map +1 -0
- package/dist/dataview/dataAttribute.d.ts +6 -0
- package/dist/dataview/dataAttribute.d.ts.map +1 -0
- package/dist/dataview/export.d.ts +46 -0
- package/dist/dataview/export.d.ts.map +1 -0
- package/dist/dataview/filterComponents.d.ts +127 -0
- package/dist/dataview/filterComponents.d.ts.map +1 -0
- package/dist/dataview/filterContext.d.ts +10 -0
- package/dist/dataview/filterContext.d.ts.map +1 -0
- package/dist/dataview/filterHooks.d.ts +74 -0
- package/dist/dataview/filterHooks.d.ts.map +1 -0
- package/dist/dataview/filterScope.d.ts +54 -0
- package/dist/dataview/filterScope.d.ts.map +1 -0
- package/dist/dataview/filterWrappers.d.ts +65 -0
- package/dist/dataview/filterWrappers.d.ts.map +1 -0
- package/dist/dataview/index.d.ts +21 -0
- package/dist/dataview/index.d.ts.map +1 -0
- package/dist/dataview/infiniteLoad.d.ts +32 -0
- package/dist/dataview/infiniteLoad.d.ts.map +1 -0
- package/dist/dataview/loaderComponents.d.ts +80 -0
- package/dist/dataview/loaderComponents.d.ts.map +1 -0
- package/dist/dataview/pagingComponents.d.ts +50 -0
- package/dist/dataview/pagingComponents.d.ts.map +1 -0
- package/dist/dataview/renderCellValue.d.ts +9 -0
- package/dist/dataview/renderCellValue.d.ts.map +1 -0
- package/dist/dataview/selectionComponents.d.ts +62 -0
- package/dist/dataview/selectionComponents.d.ts.map +1 -0
- package/dist/dataview/sortingComponents.d.ts +39 -0
- package/dist/dataview/sortingComponents.d.ts.map +1 -0
- package/dist/dataview/stateStorage.d.ts +19 -0
- package/dist/dataview/stateStorage.d.ts.map +1 -0
- package/dist/dataview/useDataView.d.ts +58 -0
- package/dist/dataview/useDataView.d.ts.map +1 -0
- package/dist/dataview/useDataViewState.d.ts +89 -0
- package/dist/dataview/useDataViewState.d.ts.map +1 -0
- package/dist/hooks/BackendAdapterContext.d.ts +110 -0
- package/dist/hooks/BackendAdapterContext.d.ts.map +1 -0
- package/dist/hooks/ContemberBindxProvider.d.ts +67 -0
- package/dist/hooks/ContemberBindxProvider.d.ts.map +1 -0
- package/dist/hooks/createBindx.d.ts +39 -0
- package/dist/hooks/createBindx.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useBindxEvents.d.ts +83 -0
- package/dist/hooks/useBindxEvents.d.ts.map +1 -0
- package/dist/hooks/useEntity.d.ts +123 -0
- package/dist/hooks/useEntity.d.ts.map +1 -0
- package/dist/hooks/useEntityBeforePersist.d.ts +22 -0
- package/dist/hooks/useEntityBeforePersist.d.ts.map +1 -0
- package/dist/hooks/useEntityCore.d.ts +52 -0
- package/dist/hooks/useEntityCore.d.ts.map +1 -0
- package/dist/hooks/useEntityImpl.d.ts +105 -0
- package/dist/hooks/useEntityImpl.d.ts.map +1 -0
- package/dist/hooks/useEntityList.d.ts +102 -0
- package/dist/hooks/useEntityList.d.ts.map +1 -0
- package/dist/hooks/useEntityListCore.d.ts +49 -0
- package/dist/hooks/useEntityListCore.d.ts.map +1 -0
- package/dist/hooks/useEntityListImpl.d.ts +70 -0
- package/dist/hooks/useEntityListImpl.d.ts.map +1 -0
- package/dist/hooks/useErrors.d.ts +72 -0
- package/dist/hooks/useErrors.d.ts.map +1 -0
- package/dist/hooks/usePersist.d.ts +115 -0
- package/dist/hooks/usePersist.d.ts.map +1 -0
- package/dist/hooks/useSelectionCollection.d.ts +41 -0
- package/dist/hooks/useSelectionCollection.d.ts.map +1 -0
- package/dist/hooks/useSelectionCollectionForList.d.ts +40 -0
- package/dist/hooks/useSelectionCollectionForList.d.ts.map +1 -0
- package/dist/hooks/useStableSelectionMeta.d.ts +11 -0
- package/dist/hooks/useStableSelectionMeta.d.ts.map +1 -0
- package/dist/hooks/useStoreSubscription.d.ts +19 -0
- package/dist/hooks/useStoreSubscription.d.ts.map +1 -0
- package/dist/hooks/useUndo.d.ts +45 -0
- package/dist/hooks/useUndo.d.ts.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/jsx/SelectionMeta.d.ts +2 -0
- package/dist/jsx/SelectionMeta.d.ts.map +1 -0
- package/dist/jsx/analyzer.d.ts +22 -0
- package/dist/jsx/analyzer.d.ts.map +1 -0
- package/dist/jsx/collectorProxy.d.ts +14 -0
- package/dist/jsx/collectorProxy.d.ts.map +1 -0
- package/dist/jsx/componentBuilder.d.ts +51 -0
- package/dist/jsx/componentBuilder.d.ts.map +1 -0
- package/dist/jsx/componentBuilder.types.d.ts +268 -0
- package/dist/jsx/componentBuilder.types.d.ts.map +1 -0
- package/dist/jsx/componentBuilderCompat.d.ts +17 -0
- package/dist/jsx/componentBuilderCompat.d.ts.map +1 -0
- package/dist/jsx/componentFactory.d.ts +39 -0
- package/dist/jsx/componentFactory.d.ts.map +1 -0
- package/dist/jsx/components/Entity.d.ts +82 -0
- package/dist/jsx/components/Entity.d.ts.map +1 -0
- package/dist/jsx/components/EntityList.d.ts +48 -0
- package/dist/jsx/components/EntityList.d.ts.map +1 -0
- package/dist/jsx/components/Field.d.ts +27 -0
- package/dist/jsx/components/Field.d.ts.map +1 -0
- package/dist/jsx/components/HasMany.d.ts +34 -0
- package/dist/jsx/components/HasMany.d.ts.map +1 -0
- package/dist/jsx/components/HasOne.d.ts +25 -0
- package/dist/jsx/components/HasOne.d.ts.map +1 -0
- package/dist/jsx/components/HasRole.d.ts +51 -0
- package/dist/jsx/components/HasRole.d.ts.map +1 -0
- package/dist/jsx/components/If.d.ts +51 -0
- package/dist/jsx/components/If.d.ts.map +1 -0
- package/dist/jsx/components/Show.d.ts +33 -0
- package/dist/jsx/components/Show.d.ts.map +1 -0
- package/dist/jsx/components/index.d.ts +8 -0
- package/dist/jsx/components/index.d.ts.map +1 -0
- package/dist/jsx/conditions.d.ts +310 -0
- package/dist/jsx/conditions.d.ts.map +1 -0
- package/dist/jsx/createComponent.d.ts +44 -0
- package/dist/jsx/createComponent.d.ts.map +1 -0
- package/dist/jsx/index.d.ts +19 -0
- package/dist/jsx/index.d.ts.map +1 -0
- package/dist/jsx/inlineProxy.d.ts +14 -0
- package/dist/jsx/inlineProxy.d.ts.map +1 -0
- package/dist/jsx/legacyTypes.d.ts +26 -0
- package/dist/jsx/legacyTypes.d.ts.map +1 -0
- package/dist/jsx/proxy.d.ts +2 -0
- package/dist/jsx/proxy.d.ts.map +1 -0
- package/dist/jsx/proxyShared.d.ts +14 -0
- package/dist/jsx/proxyShared.d.ts.map +1 -0
- package/dist/jsx/runtimeProxy.d.ts +11 -0
- package/dist/jsx/runtimeProxy.d.ts.map +1 -0
- package/dist/jsx/standaloneCreateComponent.d.ts +30 -0
- package/dist/jsx/standaloneCreateComponent.d.ts.map +1 -0
- package/dist/jsx/types.d.ts +109 -0
- package/dist/jsx/types.d.ts.map +1 -0
- package/dist/jsx/withCollector.d.ts +39 -0
- package/dist/jsx/withCollector.d.ts.map +1 -0
- package/dist/roles/RoleContext.d.ts +31 -0
- package/dist/roles/RoleContext.d.ts.map +1 -0
- package/dist/roles/index.d.ts +2 -0
- package/dist/roles/index.d.ts.map +1 -0
- package/package.json +34 -0
- package/src/batching/QueryBatcher.ts +114 -0
- package/src/batching/index.ts +1 -0
- package/src/components/EntityScope.tsx +43 -0
- package/src/hooks/BackendAdapterContext.tsx +214 -0
- package/src/hooks/ContemberBindxProvider.tsx +158 -0
- package/src/hooks/index.ts +61 -0
- package/src/hooks/useBindxEvents.ts +229 -0
- package/src/hooks/useEntity.ts +489 -0
- package/src/hooks/useEntityBeforePersist.ts +32 -0
- package/src/hooks/useEntityList.ts +444 -0
- package/src/hooks/useErrors.ts +150 -0
- package/src/hooks/usePersist.ts +377 -0
- package/src/hooks/useSelectionCollection.ts +122 -0
- package/src/hooks/useStoreSubscription.ts +51 -0
- package/src/hooks/useUndo.ts +83 -0
- package/src/index.ts +357 -0
- package/src/jsx/SelectionMeta.ts +2 -0
- package/src/jsx/analyzer.ts +261 -0
- package/src/jsx/collectorProxy.ts +282 -0
- package/src/jsx/componentBuilder.ts +180 -0
- package/src/jsx/componentBuilder.types.ts +463 -0
- package/src/jsx/componentBuilderCompat.ts +39 -0
- package/src/jsx/componentFactory.ts +400 -0
- package/src/jsx/components/Entity.tsx +383 -0
- package/src/jsx/components/EntityList.tsx +147 -0
- package/src/jsx/components/Field.tsx +79 -0
- package/src/jsx/components/HasMany.tsx +109 -0
- package/src/jsx/components/HasOne.tsx +78 -0
- package/src/jsx/components/HasRole.tsx +95 -0
- package/src/jsx/components/If.tsx +127 -0
- package/src/jsx/components/Show.tsx +56 -0
- package/src/jsx/components/index.ts +20 -0
- package/src/jsx/conditions.ts +472 -0
- package/src/jsx/createComponent.ts +175 -0
- package/src/jsx/index.ts +135 -0
- package/src/jsx/legacyTypes.ts +30 -0
- package/src/jsx/proxy.ts +1 -0
- package/src/jsx/proxyShared.ts +42 -0
- package/src/jsx/standaloneCreateComponent.ts +47 -0
- package/src/jsx/types.ts +192 -0
- package/src/jsx/withCollector.ts +45 -0
- package/src/roles/RoleContext.tsx +57 -0
- package/src/roles/index.ts +1 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Bindx - Type-safe React data binding framework
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Re-export core types and functions from @contember/bindx
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
export type {
|
|
12
|
+
// Schema types
|
|
13
|
+
RelationType,
|
|
14
|
+
ScalarFieldDef,
|
|
15
|
+
HasOneRelationDef,
|
|
16
|
+
HasManyRelationDef,
|
|
17
|
+
FieldDef,
|
|
18
|
+
EntitySchemaDef,
|
|
19
|
+
SchemaDefinition,
|
|
20
|
+
InferModel,
|
|
21
|
+
InferEntityNames,
|
|
22
|
+
EntityDef,
|
|
23
|
+
InferEntityDef,
|
|
24
|
+
// Role types
|
|
25
|
+
UnionToIntersection,
|
|
26
|
+
RoleNames,
|
|
27
|
+
CommonEntity,
|
|
28
|
+
EntityForRoles,
|
|
29
|
+
ResolveEntity,
|
|
30
|
+
SingleRoleMap,
|
|
31
|
+
DefaultRole,
|
|
32
|
+
// Selection types
|
|
33
|
+
SelectionBuilder,
|
|
34
|
+
SelectionMeta,
|
|
35
|
+
SelectionFieldMeta,
|
|
36
|
+
FluentFragment,
|
|
37
|
+
FluentDefiner,
|
|
38
|
+
HasManyOptions,
|
|
39
|
+
InferSelection,
|
|
40
|
+
QuerySpec,
|
|
41
|
+
QueryFieldSpec,
|
|
42
|
+
// Query types (typed filter/orderBy)
|
|
43
|
+
EntityWhere,
|
|
44
|
+
EntityOrderBy,
|
|
45
|
+
ScalarCondition,
|
|
46
|
+
OrderDirection,
|
|
47
|
+
TypedHasManyOptions,
|
|
48
|
+
AliasOptions,
|
|
49
|
+
// Handle types
|
|
50
|
+
HasOneRelationState,
|
|
51
|
+
InputProps,
|
|
52
|
+
EntityFields,
|
|
53
|
+
SelectedEntityFields,
|
|
54
|
+
ScalarKeys,
|
|
55
|
+
HasManyKeys,
|
|
56
|
+
HasOneKeys,
|
|
57
|
+
FieldRefMeta,
|
|
58
|
+
FieldRef,
|
|
59
|
+
HasManyRef,
|
|
60
|
+
HasOneRef,
|
|
61
|
+
EntityRef,
|
|
62
|
+
// Type extraction helpers
|
|
63
|
+
ExtractHasOneEntityName,
|
|
64
|
+
ExtractHasManyEntityName,
|
|
65
|
+
ExtractRoleMap,
|
|
66
|
+
// Adapter types
|
|
67
|
+
BackendAdapter,
|
|
68
|
+
QueryOptions,
|
|
69
|
+
Query,
|
|
70
|
+
GetQuery,
|
|
71
|
+
ListQuery,
|
|
72
|
+
QueryResult,
|
|
73
|
+
GetQueryResult,
|
|
74
|
+
ListQueryResult,
|
|
75
|
+
MockDataStore,
|
|
76
|
+
MockAdapterOptions,
|
|
77
|
+
ContemberAdapterOptions,
|
|
78
|
+
// Core types
|
|
79
|
+
EntityLoadResult,
|
|
80
|
+
EntityListLoadResult,
|
|
81
|
+
LoadEntityOptions,
|
|
82
|
+
LoadEntityListOptions,
|
|
83
|
+
SelectionInput,
|
|
84
|
+
CoreFluentDefiner,
|
|
85
|
+
// Store types
|
|
86
|
+
EntitySnapshot,
|
|
87
|
+
FieldSnapshot,
|
|
88
|
+
HasOneRelationSnapshot,
|
|
89
|
+
HasManySnapshot,
|
|
90
|
+
EntityState,
|
|
91
|
+
LoadStatus,
|
|
92
|
+
// Undo types
|
|
93
|
+
UndoManagerConfig,
|
|
94
|
+
UndoState,
|
|
95
|
+
UndoEntry,
|
|
96
|
+
// Event types
|
|
97
|
+
BindxEvent,
|
|
98
|
+
FieldScopedEvent,
|
|
99
|
+
FieldChangingEvent,
|
|
100
|
+
FieldChangedEvent,
|
|
101
|
+
RelationConnectingEvent,
|
|
102
|
+
RelationConnectedEvent,
|
|
103
|
+
RelationDisconnectingEvent,
|
|
104
|
+
RelationDisconnectedEvent,
|
|
105
|
+
RelationDeletingEvent,
|
|
106
|
+
RelationDeletedEvent,
|
|
107
|
+
HasManyConnectingEvent,
|
|
108
|
+
HasManyConnectedEvent,
|
|
109
|
+
HasManyDisconnectingEvent,
|
|
110
|
+
HasManyDisconnectedEvent,
|
|
111
|
+
EntityPersistingEvent,
|
|
112
|
+
EntityPersistedEvent,
|
|
113
|
+
EntityPersistFailedEvent,
|
|
114
|
+
EntityResettingEvent,
|
|
115
|
+
EntityResetEvent,
|
|
116
|
+
EntityDeletingEvent,
|
|
117
|
+
EntityDeletedEvent,
|
|
118
|
+
ErrorAddedEvent,
|
|
119
|
+
ErrorsClearedEvent,
|
|
120
|
+
LoadStateChangedEvent,
|
|
121
|
+
BeforeEvent,
|
|
122
|
+
AfterEvent,
|
|
123
|
+
AnyBindxEvent,
|
|
124
|
+
EventTypeMap,
|
|
125
|
+
InterceptorResult,
|
|
126
|
+
Interceptor,
|
|
127
|
+
EventListener,
|
|
128
|
+
Unsubscribe,
|
|
129
|
+
BeforeEventTypes,
|
|
130
|
+
AfterEventTypes,
|
|
131
|
+
} from '@contember/bindx'
|
|
132
|
+
|
|
133
|
+
export {
|
|
134
|
+
// Schema utilities
|
|
135
|
+
scalar,
|
|
136
|
+
hasOne,
|
|
137
|
+
hasMany,
|
|
138
|
+
defineSchema,
|
|
139
|
+
entityDef,
|
|
140
|
+
roleEntityDef,
|
|
141
|
+
DEFAULT_ROLE,
|
|
142
|
+
SchemaRegistry,
|
|
143
|
+
// Selection utilities
|
|
144
|
+
createFragment,
|
|
145
|
+
buildQueryFromSelection,
|
|
146
|
+
// Handles
|
|
147
|
+
EntityHandle,
|
|
148
|
+
HasOneHandle,
|
|
149
|
+
HasManyListHandle,
|
|
150
|
+
FieldHandle,
|
|
151
|
+
// Handle symbols
|
|
152
|
+
FIELD_REF_META,
|
|
153
|
+
// Adapter
|
|
154
|
+
MockAdapter,
|
|
155
|
+
ContemberAdapter,
|
|
156
|
+
// Core
|
|
157
|
+
createEntityLoader,
|
|
158
|
+
resolveSelectionMeta,
|
|
159
|
+
buildQuery,
|
|
160
|
+
// Store
|
|
161
|
+
SnapshotStore,
|
|
162
|
+
ActionDispatcher,
|
|
163
|
+
// ID type detection
|
|
164
|
+
isTempId,
|
|
165
|
+
isPlaceholderId,
|
|
166
|
+
isPersistedId,
|
|
167
|
+
generatePlaceholderId,
|
|
168
|
+
// Persistence
|
|
169
|
+
BatchPersister,
|
|
170
|
+
ChangeRegistry,
|
|
171
|
+
// Undo
|
|
172
|
+
UndoManager,
|
|
173
|
+
// Events
|
|
174
|
+
EventEmitter,
|
|
175
|
+
// Internal
|
|
176
|
+
__internal,
|
|
177
|
+
} from '@contember/bindx'
|
|
178
|
+
|
|
179
|
+
// ============================================================================
|
|
180
|
+
// React-specific types
|
|
181
|
+
// ============================================================================
|
|
182
|
+
|
|
183
|
+
// Hook types
|
|
184
|
+
export type {
|
|
185
|
+
BindxProviderProps,
|
|
186
|
+
BindxContextValue,
|
|
187
|
+
UseEntityOptions,
|
|
188
|
+
UseEntityListOptions,
|
|
189
|
+
LoadingEntityAccessor,
|
|
190
|
+
ErrorEntityAccessor,
|
|
191
|
+
NotFoundEntityAccessor,
|
|
192
|
+
ReadyEntityAccessor,
|
|
193
|
+
EntityAccessorResult,
|
|
194
|
+
LoadingEntityListAccessor,
|
|
195
|
+
ErrorEntityListAccessor,
|
|
196
|
+
ReadyEntityListAccessor,
|
|
197
|
+
EntityListAccessorResult,
|
|
198
|
+
// Persistence hook types
|
|
199
|
+
PersistApi,
|
|
200
|
+
EntityPersistApi,
|
|
201
|
+
AnyRefWithMeta,
|
|
202
|
+
} from './hooks/index.js'
|
|
203
|
+
|
|
204
|
+
// Persistence types from @contember/bindx
|
|
205
|
+
export type {
|
|
206
|
+
DirtyEntity,
|
|
207
|
+
PersistScope,
|
|
208
|
+
AllScope,
|
|
209
|
+
EntityScope as EntityPersistScope,
|
|
210
|
+
FieldsScope,
|
|
211
|
+
RelationScope,
|
|
212
|
+
CustomScope,
|
|
213
|
+
EntityPersistResult,
|
|
214
|
+
PersistenceResult,
|
|
215
|
+
BatchPersistOptions,
|
|
216
|
+
} from '@contember/bindx'
|
|
217
|
+
|
|
218
|
+
// JSX types
|
|
219
|
+
export type {
|
|
220
|
+
EntityAccessor,
|
|
221
|
+
FieldRefBase,
|
|
222
|
+
FieldProps,
|
|
223
|
+
HasManyProps,
|
|
224
|
+
HasOneProps,
|
|
225
|
+
IfProps,
|
|
226
|
+
EntityComponentProps,
|
|
227
|
+
HasManyComponentOptions,
|
|
228
|
+
ShowProps,
|
|
229
|
+
SelectionPropMeta,
|
|
230
|
+
SelectionProvider,
|
|
231
|
+
EntityPropKeys,
|
|
232
|
+
EntityFromProp,
|
|
233
|
+
SelectionFromProp,
|
|
234
|
+
ImplicitFragmentProperties,
|
|
235
|
+
// Component builder types
|
|
236
|
+
BindxComponentBase,
|
|
237
|
+
BindxComponent,
|
|
238
|
+
ComponentBuilder,
|
|
239
|
+
ComponentBuilderState,
|
|
240
|
+
CreateComponentOptions,
|
|
241
|
+
// Interface types
|
|
242
|
+
InterfaceEntityPropConfig,
|
|
243
|
+
ImplicitInterfaceEntityConfig,
|
|
244
|
+
ExplicitInterfaceEntityConfig,
|
|
245
|
+
AddInterfaces,
|
|
246
|
+
InterfaceSelectorsMap,
|
|
247
|
+
AnyEntityPropConfig,
|
|
248
|
+
// Entity prop config types
|
|
249
|
+
EntityPropConfig,
|
|
250
|
+
ImplicitEntityConfig,
|
|
251
|
+
ExplicitEntityConfig,
|
|
252
|
+
// State helpers
|
|
253
|
+
AddImplicitEntity,
|
|
254
|
+
AddExplicitEntity,
|
|
255
|
+
AddImplicitInterfaceEntity,
|
|
256
|
+
AddExplicitInterfaceEntity,
|
|
257
|
+
SetScalarProps,
|
|
258
|
+
// Props building
|
|
259
|
+
BuildEntityProps,
|
|
260
|
+
BuildProps,
|
|
261
|
+
BuildFragmentProps,
|
|
262
|
+
InitialBuilderState,
|
|
263
|
+
} from './jsx/index.js'
|
|
264
|
+
|
|
265
|
+
// ============================================================================
|
|
266
|
+
// React-specific functions & components
|
|
267
|
+
// ============================================================================
|
|
268
|
+
|
|
269
|
+
// Hooks
|
|
270
|
+
export {
|
|
271
|
+
BindxProvider,
|
|
272
|
+
useBackendAdapter,
|
|
273
|
+
useSnapshotStore,
|
|
274
|
+
useDispatcher,
|
|
275
|
+
useBatchPersister,
|
|
276
|
+
useBindxContext,
|
|
277
|
+
useSchemaRegistry,
|
|
278
|
+
// Standalone hooks
|
|
279
|
+
useEntity,
|
|
280
|
+
useEntityList,
|
|
281
|
+
// Persistence
|
|
282
|
+
usePersist,
|
|
283
|
+
usePersistEntity,
|
|
284
|
+
// Undo
|
|
285
|
+
useUndo,
|
|
286
|
+
// Events
|
|
287
|
+
useOnEvent,
|
|
288
|
+
useOnEntityEvent,
|
|
289
|
+
useOnFieldEvent,
|
|
290
|
+
useIntercept,
|
|
291
|
+
useInterceptEntity,
|
|
292
|
+
useInterceptField,
|
|
293
|
+
// Contember
|
|
294
|
+
ContemberBindxProvider,
|
|
295
|
+
schemaNamesToDef,
|
|
296
|
+
} from './hooks/index.js'
|
|
297
|
+
|
|
298
|
+
// Role context
|
|
299
|
+
export { RoleProvider, useHasRole, type RoleProviderProps } from './roles/index.js'
|
|
300
|
+
|
|
301
|
+
// Undo hook types
|
|
302
|
+
export type { UndoHookResult } from './hooks/useUndo.js'
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
// JSX Components
|
|
306
|
+
export {
|
|
307
|
+
Field,
|
|
308
|
+
HasMany,
|
|
309
|
+
HasOne,
|
|
310
|
+
If,
|
|
311
|
+
Show,
|
|
312
|
+
Entity,
|
|
313
|
+
type EntityProps,
|
|
314
|
+
EntityList,
|
|
315
|
+
type EntityListProps,
|
|
316
|
+
HasRole,
|
|
317
|
+
type HasRoleProps,
|
|
318
|
+
BINDX_COMPONENT,
|
|
319
|
+
// Condition DSL for <If> component
|
|
320
|
+
cond,
|
|
321
|
+
type Condition,
|
|
322
|
+
// Component (unified API)
|
|
323
|
+
createComponent,
|
|
324
|
+
withCollector,
|
|
325
|
+
isBindxComponent,
|
|
326
|
+
mergeFragments,
|
|
327
|
+
COMPONENT_MARKER,
|
|
328
|
+
COMPONENT_BRAND,
|
|
329
|
+
COMPONENT_SELECTIONS,
|
|
330
|
+
createComponentBuilder,
|
|
331
|
+
getComponentBrand,
|
|
332
|
+
setBrandValidation,
|
|
333
|
+
validateBrand,
|
|
334
|
+
} from './jsx/index.js'
|
|
335
|
+
|
|
336
|
+
// Entity Scope
|
|
337
|
+
export {
|
|
338
|
+
EntityScope,
|
|
339
|
+
useEntityScope,
|
|
340
|
+
useOptionalEntityScope,
|
|
341
|
+
type EntityScopeProps,
|
|
342
|
+
} from './components/EntityScope.js'
|
|
343
|
+
|
|
344
|
+
// ============================================================================
|
|
345
|
+
// Internal React API
|
|
346
|
+
// ============================================================================
|
|
347
|
+
|
|
348
|
+
export {
|
|
349
|
+
SelectionMetaCollector,
|
|
350
|
+
mergeSelections,
|
|
351
|
+
createEmptySelection,
|
|
352
|
+
createCollectorProxy,
|
|
353
|
+
analyzeJsx,
|
|
354
|
+
collectSelection,
|
|
355
|
+
convertToQuerySelection,
|
|
356
|
+
debugSelection,
|
|
357
|
+
} from './jsx/index.js'
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import type { ReactNode, ReactElement } from 'react'
|
|
2
|
+
import { isValidElement } from 'react'
|
|
3
|
+
import type { SelectionMeta, SelectionFieldMeta, SelectionProvider } from './types.js'
|
|
4
|
+
import { FIELD_REF_META, SCOPE_REF } from './types.js'
|
|
5
|
+
import { SelectionMetaCollector, mergeSelections } from './SelectionMeta.js'
|
|
6
|
+
import { SelectionScope } from '@contember/bindx'
|
|
7
|
+
import { isBindxComponent, COMPONENT_SELECTIONS } from './createComponent.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Analyzes JSX tree to extract field selection metadata.
|
|
11
|
+
* This is called during the collection phase to determine which fields need to be fetched.
|
|
12
|
+
*/
|
|
13
|
+
export function analyzeJsx(node: ReactNode, selection: SelectionMetaCollector): void {
|
|
14
|
+
// Handle null/undefined
|
|
15
|
+
if (node === null || node === undefined) {
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Handle primitives (string, number, boolean)
|
|
20
|
+
if (typeof node !== 'object') {
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Handle arrays
|
|
25
|
+
if (Array.isArray(node)) {
|
|
26
|
+
for (const child of node) {
|
|
27
|
+
analyzeJsx(child, selection)
|
|
28
|
+
}
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Must be a React element at this point
|
|
33
|
+
if (!isValidElement(node)) {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const element = node as ReactElement<{ children?: ReactNode }>
|
|
38
|
+
|
|
39
|
+
// Handle React Fragment and host elements (div, span, etc.) - just analyze children
|
|
40
|
+
if (typeof element.type === 'symbol' || typeof element.type === 'string') {
|
|
41
|
+
if (element.props.children) {
|
|
42
|
+
analyzeJsx(element.props.children, selection)
|
|
43
|
+
}
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Handle function components
|
|
48
|
+
const component = element.type as unknown
|
|
49
|
+
|
|
50
|
+
// Check if it's a bindx component with pre-computed selection - needs special handling
|
|
51
|
+
if (isBindxComponent(component)) {
|
|
52
|
+
// First, trigger implicit collection if the component has getSelection
|
|
53
|
+
// This ensures lazy implicit selections are collected before we access COMPONENT_SELECTIONS
|
|
54
|
+
const componentObj = component as Record<string, unknown>
|
|
55
|
+
if ('getSelection' in componentObj && typeof componentObj['getSelection'] === 'function') {
|
|
56
|
+
;(component as SelectionProvider).getSelection(element.props as Record<string, unknown>, () => new SelectionMetaCollector())
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
handleBindxComponent(
|
|
60
|
+
component as { [COMPONENT_SELECTIONS]: Map<string, { selection: SelectionMeta }> },
|
|
61
|
+
element.props as Record<string, unknown>,
|
|
62
|
+
selection,
|
|
63
|
+
)
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check if it's a component with getSelection (memo() wrapped or plain function components)
|
|
68
|
+
if (
|
|
69
|
+
component !== null &&
|
|
70
|
+
(typeof component === 'object' || typeof component === 'function') &&
|
|
71
|
+
'getSelection' in component &&
|
|
72
|
+
typeof (component as SelectionProvider).getSelection === 'function'
|
|
73
|
+
) {
|
|
74
|
+
const provider = component as SelectionProvider
|
|
75
|
+
|
|
76
|
+
// Collector function for nested selection analysis
|
|
77
|
+
const collectNested = (children: ReactNode): SelectionMeta => {
|
|
78
|
+
const nestedSelection = new SelectionMetaCollector()
|
|
79
|
+
analyzeJsx(children, nestedSelection)
|
|
80
|
+
return nestedSelection
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Get selection info from the component
|
|
84
|
+
const fieldSelection = provider.getSelection(element.props, collectNested)
|
|
85
|
+
|
|
86
|
+
// Add to selection
|
|
87
|
+
if (fieldSelection) {
|
|
88
|
+
if (Array.isArray(fieldSelection)) {
|
|
89
|
+
for (const field of fieldSelection) {
|
|
90
|
+
selection.addField(field)
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
selection.addField(fieldSelection)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Check if component has staticRender — like Contember OSS's Component(render, staticRender) pattern.
|
|
101
|
+
// staticRender receives the same props (with collector proxies during analysis) and returns JSX to analyze.
|
|
102
|
+
if (
|
|
103
|
+
component !== null &&
|
|
104
|
+
(typeof component === 'object' || typeof component === 'function') &&
|
|
105
|
+
'staticRender' in component &&
|
|
106
|
+
typeof (component as { staticRender: unknown }).staticRender === 'function'
|
|
107
|
+
) {
|
|
108
|
+
const staticJsx = (component as { staticRender: (props: Record<string, unknown>) => ReactNode }).staticRender(
|
|
109
|
+
element.props as Record<string, unknown>,
|
|
110
|
+
)
|
|
111
|
+
if (staticJsx) {
|
|
112
|
+
analyzeJsx(staticJsx, selection)
|
|
113
|
+
}
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// For non-bindx components, try to analyze children
|
|
118
|
+
// This handles wrapper components that pass children through
|
|
119
|
+
const children = element.props.children
|
|
120
|
+
if (children) {
|
|
121
|
+
analyzeJsx(children, selection)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Collects all field selections from a JSX tree.
|
|
127
|
+
* Entry point for the collection phase.
|
|
128
|
+
*/
|
|
129
|
+
export function collectSelection(jsx: ReactNode): SelectionMetaCollector {
|
|
130
|
+
const selection = new SelectionMetaCollector()
|
|
131
|
+
analyzeJsx(jsx, selection)
|
|
132
|
+
return selection
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Converts JSX selection metadata to the format used by query builder
|
|
137
|
+
*/
|
|
138
|
+
export function convertToQuerySelection(jsxSelection: SelectionMeta): Record<string, unknown> {
|
|
139
|
+
const result: Record<string, unknown> = {}
|
|
140
|
+
|
|
141
|
+
for (const [_, field] of jsxSelection.fields) {
|
|
142
|
+
if (field.path.length !== 1) {
|
|
143
|
+
// Skip nested paths - they're handled by parent relations
|
|
144
|
+
continue
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (field.isRelation && field.nested) {
|
|
148
|
+
// Relation with nested selection
|
|
149
|
+
const nestedQuery = convertToQuerySelection(field.nested)
|
|
150
|
+
|
|
151
|
+
if (field.isArray && field.hasManyParams) {
|
|
152
|
+
// HasMany with params
|
|
153
|
+
result[field.fieldName] = {
|
|
154
|
+
...nestedQuery,
|
|
155
|
+
__params: field.hasManyParams,
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
result[field.fieldName] = nestedQuery
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
// Scalar field
|
|
162
|
+
result[field.fieldName] = true
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return result
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Handles bindx component in JSX analysis.
|
|
171
|
+
* Merges the component's pre-computed selection into the parent selection,
|
|
172
|
+
* adjusted to the correct path context based on the entity prop.
|
|
173
|
+
*/
|
|
174
|
+
function handleBindxComponent(
|
|
175
|
+
component: { [COMPONENT_SELECTIONS]: Map<string, { selection: SelectionMeta }> },
|
|
176
|
+
props: Record<string, unknown>,
|
|
177
|
+
parentSelection: SelectionMetaCollector,
|
|
178
|
+
): void {
|
|
179
|
+
const entityPropsMap = component[COMPONENT_SELECTIONS]
|
|
180
|
+
// For each entity prop in the fragment component
|
|
181
|
+
for (const [propName, meta] of entityPropsMap) {
|
|
182
|
+
const propValue = props[propName]
|
|
183
|
+
|
|
184
|
+
if (!propValue || typeof propValue !== 'object') {
|
|
185
|
+
continue
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Case 1: Prop has SCOPE_REF - direct reference to SelectionScope
|
|
189
|
+
// This is the case when passing relation.entity to a nested component
|
|
190
|
+
if (SCOPE_REF in propValue) {
|
|
191
|
+
const targetScope = (propValue as { [SCOPE_REF]: SelectionScope })[SCOPE_REF]
|
|
192
|
+
// Merge the nested component's selection directly into the relation's scope
|
|
193
|
+
targetScope.mergeFromSelectionMeta(meta.selection)
|
|
194
|
+
}
|
|
195
|
+
// Case 2: Prop is a FieldRef from a relation (e.g., article.fields.author)
|
|
196
|
+
// This has FIELD_REF_META with a path to adjust
|
|
197
|
+
else if (FIELD_REF_META in propValue) {
|
|
198
|
+
const refMeta = (propValue as { [FIELD_REF_META]: { path: string[]; fieldName: string } })[FIELD_REF_META]
|
|
199
|
+
|
|
200
|
+
// Add fields with adjusted paths to parent selection
|
|
201
|
+
for (const [_key, field] of meta.selection.fields) {
|
|
202
|
+
// Only process root-level fields from the fragment
|
|
203
|
+
if (field.path.length === 1) {
|
|
204
|
+
// Create a new field meta with the path adjusted to the parent context
|
|
205
|
+
const adjustedField: SelectionFieldMeta = {
|
|
206
|
+
...field,
|
|
207
|
+
path: [...refMeta.path, ...field.path],
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// If the field has nested selection, we need to preserve it
|
|
211
|
+
if (field.nested) {
|
|
212
|
+
adjustedField.nested = field.nested
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
parentSelection.addField(adjustedField)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Case 3: Prop is an EntityRef from Entity children callback (root level)
|
|
220
|
+
// This doesn't have FIELD_REF_META, just merge the fields directly
|
|
221
|
+
else if ('id' in propValue && 'fields' in propValue) {
|
|
222
|
+
// This is an EntityRef - merge fragment's selection directly
|
|
223
|
+
for (const [_key, field] of meta.selection.fields) {
|
|
224
|
+
if (field.path.length === 1) {
|
|
225
|
+
parentSelection.addField({ ...field })
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Debug helper - prints selection tree
|
|
234
|
+
*/
|
|
235
|
+
export function debugSelection(selection: SelectionMeta, indent = 0): string {
|
|
236
|
+
const lines: string[] = []
|
|
237
|
+
const prefix = ' '.repeat(indent)
|
|
238
|
+
|
|
239
|
+
for (const [key, field] of selection.fields) {
|
|
240
|
+
let line = `${prefix}${field.fieldName}`
|
|
241
|
+
|
|
242
|
+
if (field.isArray) {
|
|
243
|
+
line += '[]'
|
|
244
|
+
}
|
|
245
|
+
if (field.isRelation) {
|
|
246
|
+
line += ' (relation)'
|
|
247
|
+
}
|
|
248
|
+
if (field.hasManyParams) {
|
|
249
|
+
const params = JSON.stringify(field.hasManyParams)
|
|
250
|
+
line += ` ${params}`
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
lines.push(line)
|
|
254
|
+
|
|
255
|
+
if (field.nested) {
|
|
256
|
+
lines.push(debugSelection(field.nested, indent + 1))
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return lines.join('\n')
|
|
261
|
+
}
|