@collective-intelligence/external-apps-client-sdk-react 0.0.0-stage → 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/README.md +140 -2
- package/dist/index-6memxjn1.js +49 -0
- package/dist/index.d.ts +958 -0
- package/dist/index.js +2 -0
- package/dist/resources.d.ts +662 -0
- package/dist/resources.js +2 -0
- package/package.json +70 -4
package/README.md
CHANGED
|
@@ -1,3 +1,141 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@collective-intelligence/external-apps-client-sdk-react`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
UI-minimal React bindings over the Promise Client SDK. The package has no private application UI dependencies.
|
|
4
|
+
|
|
5
|
+
`CollectiveIntelligenceProvider` owns a stable, request-isolated QueryClient. TanStack Query is a normal
|
|
6
|
+
SDK dependency; applications do not install it as a peer or configure a QueryClient for SDK CRUD.
|
|
7
|
+
React and React DOM remain peers.
|
|
8
|
+
|
|
9
|
+
Configure the provider's `entitySource` once, alongside its existing Promise `client`. `EntitySource`
|
|
10
|
+
exposes a stable `getSnapshot`, a `subscribe` function, and a typed `bind(contract)` function returning
|
|
11
|
+
the common Promise `EntityClient`. Authenticated snapshots identify the configured logical source,
|
|
12
|
+
application, user, and organization. Obtain those identities from the authenticated application
|
|
13
|
+
session; they are cache boundaries, not access grants. Return a new stable snapshot for every session
|
|
14
|
+
transition, notify subscribers immediately on logout, and bind clients to that snapshot's authority.
|
|
15
|
+
Backend authorization remains authoritative. `CollectiveIntelligenceLoginProvider` forwards the same
|
|
16
|
+
configuration; the entity source must subscribe to the application's CI-derived session lifecycle.
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
;<CollectiveIntelligenceProvider client={appSdk} entitySource={entitySource}>
|
|
20
|
+
<Orders />
|
|
21
|
+
</CollectiveIntelligenceProvider>
|
|
22
|
+
|
|
23
|
+
// Import these hooks from /resources. Use the portable entity contract.
|
|
24
|
+
const rows = useEntityList(orderContract, query)
|
|
25
|
+
const record = useEntityRecord(orderContract, { id: selectedId })
|
|
26
|
+
const create = useEntityCreate(orderContract)
|
|
27
|
+
const update = useEntityUpdate(orderContract, { id: selectedId })
|
|
28
|
+
const remove = useEntityDelete(orderContract, { id: selectedId })
|
|
29
|
+
|
|
30
|
+
await update.submit({ value: draft, expectedRevision: editedRecord.revision })
|
|
31
|
+
// Only on an explicit user request to deliver the same action again:
|
|
32
|
+
await update.resubmit()
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Reads expose `data`, `loading`, `refreshing`, `error`, `authState`, effective binding `capabilities`,
|
|
36
|
+
and explicit `refresh`; list reads also expose `empty`. Equivalent requests share data across views.
|
|
37
|
+
Cache identity includes source/application/user/organization and resource/version/query, never view
|
|
38
|
+
namespaces or layout settings.
|
|
39
|
+
|
|
40
|
+
Writes expose `available`, record-scoped `pending`, `status`, `data`, `error`, `submitted`, `submit`,
|
|
41
|
+
and `resubmit`. Status distinguishes `conflict`, `rejected`, and `uncertain` from ordinary
|
|
42
|
+
`idle`/`pending`/`success`. Submission clones and freezes the draft and reviewed revision and generates
|
|
43
|
+
one operation key. A new submit creates a new action; resubmit preserves the previous action exactly.
|
|
44
|
+
Keep editable drafts in the form and use `submitted` for the retained action; a successful replay
|
|
45
|
+
does not overwrite a newer draft. Same-record update/delete calls serialize across hook instances;
|
|
46
|
+
different records and separate creates remain independent. Queued writes retain their original
|
|
47
|
+
revisions. Form unmount does not cancel a dispatched write. Source transitions clear protected reads
|
|
48
|
+
and reject stale queued actions before dispatch. Queries and mutations never automatically retry;
|
|
49
|
+
there is no persistence, reload recovery, or automatic revision rebasing.
|
|
50
|
+
|
|
51
|
+
The old public TanStack option factories and native-result resource hooks are no longer exported.
|
|
52
|
+
Use the deliberate entity hooks above. Existing generic slotted `Resource*` presentation remains
|
|
53
|
+
separate from common entity CRUD.
|
|
54
|
+
|
|
55
|
+
## Declared entity views
|
|
56
|
+
|
|
57
|
+
Import `defineEntity`, `EntityTable`, `EntityList`, and `EntityForm` from
|
|
58
|
+
`@collective-intelligence/external-apps-client-sdk-react/resources`. Declare
|
|
59
|
+
presentation once alongside the portable contract:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
const orders = defineEntity({
|
|
63
|
+
contract: orderContract,
|
|
64
|
+
config: {
|
|
65
|
+
fields: { number: { label: "Order number" } },
|
|
66
|
+
table: {
|
|
67
|
+
columns: ["number"],
|
|
68
|
+
variants: { compact: { columns: ["number"] } }
|
|
69
|
+
},
|
|
70
|
+
list: { title: "number" },
|
|
71
|
+
forms: {
|
|
72
|
+
create: { fields: ["number"] },
|
|
73
|
+
update: { fields: ["number"] }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// Inside the SDK provider and the host framework's NuqsAdapter:
|
|
79
|
+
<EntityTable entity={orders} namespace="orders-main" />
|
|
80
|
+
<EntityList entity={orders} namespace="orders-sidebar" />
|
|
81
|
+
<EntityTable entity={orders} viewState="memory" variant="compact" />
|
|
82
|
+
<EntityForm entity={orders} mode="update" record={selectedOrder} />
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The declaration contains labels, field/control/renderer keys and layouts, with
|
|
86
|
+
no JSX, credentials or storage configuration. Field names are inferred from
|
|
87
|
+
the contract; configured fields must also exist in its portable schema.
|
|
88
|
+
Views render public `ui-react` presentation and share authorized query data
|
|
89
|
+
when their normalized queries match.
|
|
90
|
+
|
|
91
|
+
URL-backed tables/lists require a stable, distinct namespace. Install the host
|
|
92
|
+
adapter once; the proven TanStack Start integration uses
|
|
93
|
+
`NuqsAdapter` from `nuqs/adapters/tanstack-router` inside the router root.
|
|
94
|
+
Nuqs 2.10.1 owns URL serialization and replace-history updates. Defaults are
|
|
95
|
+
omitted; unrelated keys, other namespaces and the hash are preserved. Invalid
|
|
96
|
+
owned values fall back to defaults. Search/filter/sort changes reset the page.
|
|
97
|
+
For custom controls, use `useEntityViewState(namespace, { contract, pageSize })`;
|
|
98
|
+
it exposes `state`, the normalized `query`, and setters for page, page size,
|
|
99
|
+
search, filters and sorting. `useMemoryEntityViewState` and
|
|
100
|
+
`viewState="memory"` need no URL adapter. View namespaces never enter data keys.
|
|
101
|
+
|
|
102
|
+
Forms infer scalar, enum, date, nullable and required settings from portable
|
|
103
|
+
schemas. Readonly schema fields cannot become writable through configuration
|
|
104
|
+
and are omitted from submissions. Richer values need a named control in the
|
|
105
|
+
form's `controls` registry; missing controls produce explicit feedback.
|
|
106
|
+
Custom controls receive the field metadata and return JSON wire values.
|
|
107
|
+
Named display renderers are supplied separately through `renderers`.
|
|
108
|
+
|
|
109
|
+
Pending writes disable overlapping saves. Conflict and unknown-outcome states
|
|
110
|
+
keep the local draft; **Resubmit** sends the captured original action, including
|
|
111
|
+
its key, values and revision. Successful resubmission also keeps newer edits.
|
|
112
|
+
An update form retains the revision its draft began editing when refreshed
|
|
113
|
+
record props arrive. Remount it intentionally (for example with a React `key`)
|
|
114
|
+
after the user chooses to discard the draft and edit a newer server revision.
|
|
115
|
+
Drafts and operation keys never enter the URL.
|
|
116
|
+
|
|
117
|
+
## Workspace development
|
|
118
|
+
|
|
119
|
+
See the repository's [Effect demo](../../../demo/external-app-effect/README.md)
|
|
120
|
+
for the same declared Lead views configured against local Gateway, proxied CI,
|
|
121
|
+
and direct CI bindings.
|
|
122
|
+
|
|
123
|
+
Each package export declares an opt-in `ci-source` condition for workspace development. The local
|
|
124
|
+
TypeScript configuration enables it for the framework-neutral Client SDK, so either package's changes
|
|
125
|
+
are consumed without an intermediate rebuild. Release builds disable custom conditions; installed npm
|
|
126
|
+
consumers resolve generated `dist` JavaScript and declarations. Shared runtime chunks keep provider
|
|
127
|
+
contexts identical across the root and `/resources` entrypoints.
|
|
128
|
+
|
|
129
|
+
Run `bunx vitest run src`, `bun run type-check`, `bun run lint`, and `bun run test:pack`. The pack check
|
|
130
|
+
executes a real root-provider/resources-hook consumer without caller TanStack setup and removes its
|
|
131
|
+
temporary installation on success or failure.
|
|
132
|
+
|
|
133
|
+
## Enum value compatibility
|
|
134
|
+
|
|
135
|
+
Repository-owned enum values use lower `snake_case`. Update gateway manifests,
|
|
136
|
+
request payloads and saved resource filters together with their consumers. For
|
|
137
|
+
example, resource filters use `starts_with` and `is_null`, lifecycle operation
|
|
138
|
+
values use `soft_delete` and `hard_delete`, and gateway principal kinds use
|
|
139
|
+
`detached_user` and `service_principal`. Public method and capability property
|
|
140
|
+
names such as `softDelete` remain unchanged. External HTTP, OAuth, JSON Schema
|
|
141
|
+
and provider values retain their required spelling at their adapter boundaries.
|