@krak-stack/registry 0.1.41 → 0.1.43
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
CHANGED
|
@@ -6,41 +6,19 @@ Tree-shakable runtime components and Effect services from the KrakStack shadcn r
|
|
|
6
6
|
bun add @krak-stack/registry
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Effect forms
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
compatibility patches
|
|
14
|
-
does not apply them automatically.
|
|
15
|
-
|
|
16
|
-
After installing Registry, copy its bundled patches into your application:
|
|
11
|
+
Applications using Effect forms need `@lucas-barake/effect-form@1.1.0` and
|
|
12
|
+
`@lucas-barake/effect-form-react@1.1.0`, which support stable Effect 4 without
|
|
13
|
+
compatibility patches:
|
|
17
14
|
|
|
18
15
|
```sh
|
|
19
|
-
|
|
20
|
-
cp node_modules/@krak-stack/registry/patches/*.patch patches/
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
Merge these fields into the application's root `package.json`, preserving any
|
|
24
|
-
existing overrides and patches:
|
|
25
|
-
|
|
26
|
-
```json
|
|
27
|
-
{
|
|
28
|
-
"overrides": {
|
|
29
|
-
"@lucas-barake/effect-form": "0.25.0-beta.6",
|
|
30
|
-
"@lucas-barake/effect-form-react": "0.26.0-beta.5"
|
|
31
|
-
},
|
|
32
|
-
"patchedDependencies": {
|
|
33
|
-
"@lucas-barake/effect-form@0.25.0-beta.6": "patches/@lucas-barake%2Feffect-form@0.25.0-beta.6.patch",
|
|
34
|
-
"@lucas-barake/effect-form-react@0.26.0-beta.5": "patches/@lucas-barake%2Feffect-form-react@0.26.0-beta.5.patch"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
16
|
+
bun add @lucas-barake/effect-form@1.1.0 @lucas-barake/effect-form-react@1.1.0
|
|
37
17
|
```
|
|
38
18
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
`
|
|
42
|
-
[upstream release PR #111](https://github.com/lucas-barake/effect-form/pull/111)
|
|
43
|
-
is published.
|
|
19
|
+
When upgrading from the patched betas, remove their `patchedDependencies`
|
|
20
|
+
entries and patch files, update any form version overrides to `1.1.0`, and run
|
|
21
|
+
`bun install`. Preserve unrelated dependency patches.
|
|
44
22
|
|
|
45
23
|
## Usage
|
|
46
24
|
|
|
@@ -79,182 +57,191 @@ import {
|
|
|
79
57
|
import { NotificationService } from "@krak-stack/registry/service-notification";
|
|
80
58
|
```
|
|
81
59
|
|
|
82
|
-
|
|
60
|
+
## OpenTelemetry
|
|
61
|
+
|
|
62
|
+
| Export | Purpose |
|
|
63
|
+
| --------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
64
|
+
| `HttpApiOtlp.layer` from `opentelemetry/api` | Server exporters and same-origin browser ingestion routes. Includes `ServerOtlp.layer`. |
|
|
65
|
+
| `ServerOtlp.layer` from `opentelemetry/server` | Exporters for workers, workflows, and CLIs without an HTTP server. |
|
|
66
|
+
| `BrowserOtlp.layer(options)` from `opentelemetry/browser` | Browser tracing and optional events, logs, and metrics. |
|
|
67
|
+
|
|
68
|
+
### Setup
|
|
69
|
+
|
|
70
|
+
Provide the HTTP layer once at the application composition root:
|
|
83
71
|
|
|
84
72
|
```ts
|
|
73
|
+
import { Layer } from "effect";
|
|
74
|
+
import { HttpApiOtlp } from "@krak-stack/registry/opentelemetry/api";
|
|
75
|
+
|
|
85
76
|
const appLayer = appRoutes.pipe(Layer.provideMerge(HttpApiOtlp.layer));
|
|
86
77
|
```
|
|
87
78
|
|
|
88
|
-
|
|
79
|
+
Configure an OTLP/HTTP collector on the server:
|
|
80
|
+
|
|
81
|
+
```dotenv
|
|
82
|
+
OTEL_SERVICE_NAME=my-app-api
|
|
83
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
|
|
84
|
+
OTEL_TRACES_EXPORTER=otlp
|
|
85
|
+
OTEL_METRICS_EXPORTER=otlp
|
|
86
|
+
OTEL_LOGS_EXPORTER=otlp
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Browser events require the logs signal. The proxy forwards enabled signals from
|
|
90
|
+
`/api/otel/v1/{traces,metrics,logs}` to the collector. Keep collector credentials
|
|
91
|
+
server-side. Server log endpoint/header overrides use
|
|
92
|
+
`OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` / `OTEL_EXPORTER_OTLP_LOGS_HEADERS`, falling
|
|
93
|
+
back to the shared endpoint/headers; these overrides do not change proxy routing.
|
|
94
|
+
`OTEL_SDK_DISABLED=true` disables server export, not browser collection.
|
|
95
|
+
|
|
96
|
+
Install one browser layer on the Atom context passed to `AtomHttpApi.Service`:
|
|
89
97
|
|
|
90
98
|
```ts
|
|
91
99
|
import { Atom } from "effect/reactivity";
|
|
92
100
|
import { BrowserOtlp } from "@krak-stack/registry/opentelemetry/browser";
|
|
93
101
|
|
|
94
102
|
const apiRuntime = Atom.context();
|
|
95
|
-
|
|
96
103
|
if (!import.meta.env.SSR) {
|
|
97
|
-
apiRuntime.addGlobalLayer(
|
|
104
|
+
apiRuntime.addGlobalLayer(
|
|
105
|
+
BrowserOtlp.layer({ serviceName: "my-app-web", events: {} }),
|
|
106
|
+
);
|
|
98
107
|
}
|
|
99
108
|
```
|
|
100
109
|
|
|
101
|
-
|
|
110
|
+
Mount/read `ApiClient.runtime` in the root layout to start it. Browser methods
|
|
111
|
+
target the active layer even when run from another Effect runtime. Calls before
|
|
112
|
+
startup or after disposal are no-ops, not buffered. Dispose long-lived server and
|
|
113
|
+
browser runtimes on shutdown to flush pending data.
|
|
102
114
|
|
|
103
|
-
|
|
104
|
-
from `@krak-stack/registry/opentelemetry/server`. `HttpApiOtlp.layer` already
|
|
105
|
-
includes this layer alongside the browser proxy routes.
|
|
115
|
+
### Browser API
|
|
106
116
|
|
|
107
|
-
|
|
117
|
+
All methods return Effects. Use `yield*` inside Effect code or
|
|
118
|
+
`Effect.runPromise(...)` / `Effect.runFork(...)` from application callbacks.
|
|
119
|
+
|
|
120
|
+
| Method | Behavior |
|
|
121
|
+
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
122
|
+
| `identify({ userId?, organizationId? })` | Replace identity for future events; omitted fields clear old values. Emits no event. |
|
|
123
|
+
| `identify(null)` | Clear identity, for example on logout. |
|
|
124
|
+
| `track(name, properties?, options?)` | Record a named event. |
|
|
125
|
+
| `page(options?)` | Record `browser.page_view`. Accepts `path`, `name`, `category`, `properties`, and event `options`. `pageView` is an alias. |
|
|
126
|
+
|
|
127
|
+
`identify` has no typed failure: invalid input warns without including supplied
|
|
128
|
+
values and leaves identity unchanged. `track` and `page` fail with an Effect
|
|
129
|
+
schema error on invalid input. Identity is in memory only, applies to events
|
|
130
|
+
rather than automatic traces/logs, and never rewrites queued events.
|
|
131
|
+
|
|
132
|
+
### Auth example
|
|
133
|
+
|
|
134
|
+
Mount this once under the application's Atom registry. `ApiClient` and
|
|
135
|
+
`authSessionAtom` are application-owned; the telemetry package has no auth
|
|
136
|
+
dependency. The session atom in this example exposes KrakStack Auth session data.
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
import { useAtomSubscribe, useAtomValue } from "@effect/atom-react";
|
|
140
|
+
import { BrowserOtlp } from "@krak-stack/registry/opentelemetry/browser";
|
|
108
141
|
import { Effect } from "effect";
|
|
109
|
-
import {
|
|
142
|
+
import { AsyncResult } from "effect/reactivity";
|
|
143
|
+
import { ApiClient } from "@/lib/api-client";
|
|
144
|
+
import { authSessionAtom } from "@/services/auth/client";
|
|
145
|
+
|
|
146
|
+
export const AuthTelemetry = () => {
|
|
147
|
+
const runtime = useAtomValue(ApiClient.runtime);
|
|
148
|
+
|
|
149
|
+
useAtomSubscribe(
|
|
150
|
+
authSessionAtom,
|
|
151
|
+
(session) => {
|
|
152
|
+
if (!AsyncResult.isSuccess(runtime)) return;
|
|
153
|
+
|
|
154
|
+
Effect.runFork(
|
|
155
|
+
BrowserOtlp.identify(
|
|
156
|
+
AsyncResult.isSuccess(session) && !session.waiting && session.value
|
|
157
|
+
? {
|
|
158
|
+
userId: session.value.user.id,
|
|
159
|
+
organizationId:
|
|
160
|
+
session.value.session.activeOrganizationId ?? undefined,
|
|
161
|
+
}
|
|
162
|
+
: null,
|
|
163
|
+
),
|
|
164
|
+
);
|
|
165
|
+
},
|
|
166
|
+
{ immediate: true },
|
|
167
|
+
);
|
|
110
168
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}).pipe(Effect.provide(ServerOtlp.layer));
|
|
169
|
+
return null;
|
|
170
|
+
};
|
|
114
171
|
```
|
|
115
172
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
`
|
|
119
|
-
|
|
120
|
-
long-lived application runtime to retain batching; dispose it on shutdown to
|
|
121
|
-
flush pending events.
|
|
173
|
+
This identifies after startup and clears identity during auth loading, failure,
|
|
174
|
+
and logout. The first page view may be anonymous. For other auth libraries, pass
|
|
175
|
+
the same two IDs or `null` when auth state changes. Apply your own consent policy;
|
|
176
|
+
do not send names, emails, or session tokens as identity.
|
|
122
177
|
|
|
123
|
-
|
|
178
|
+
### Page views and browser options
|
|
124
179
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
yield* BrowserOtlp.track("app.checkout.started", {
|
|
131
|
-
"checkout.source": "cart",
|
|
132
|
-
});
|
|
133
|
-
yield* BrowserOtlp.page({
|
|
134
|
-
name: "Documentation",
|
|
135
|
-
category: "Docs",
|
|
136
|
-
path: "/docs",
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
```
|
|
180
|
+
`events: {}` enables custom events and one page view on startup, then on pathname
|
|
181
|
+
changes through `pushState`, `replaceState`, and back/forward navigation.
|
|
182
|
+
Same-path and query/hash-only changes are ignored. Tracking follows URL changes,
|
|
183
|
+
not loader completion. Paths exclude query strings/fragments but may still
|
|
184
|
+
contain personal IDs.
|
|
140
185
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
History hooks and listeners are scoped and restored on disposal. Tracking follows
|
|
145
|
-
URL changes, not framework loader completion. The first page may be anonymous if
|
|
146
|
-
identity has not been set yet; identify does not retroactively change it.
|
|
186
|
+
For sanitized route templates or custom timing, use
|
|
187
|
+
`events: { pageViews: false }` and call `page({ path: "/orders/:id" })` manually.
|
|
188
|
+
Do not combine automatic and manual tracking for the same view.
|
|
147
189
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
created. Only the pathname is captured; paths may still contain personal IDs.
|
|
190
|
+
| Layer option | Default |
|
|
191
|
+
| ----------------------------------------- | --------------------------------------------------------------- |
|
|
192
|
+
| `serviceName` | Required |
|
|
193
|
+
| `traces` | `{}`; includes global exception capture. `false` disables both. |
|
|
194
|
+
| `events`, `logs`, `metrics` | `false`; enable each independently with `{}`. |
|
|
195
|
+
| `baseUrl` | `/api/otel` |
|
|
196
|
+
| `serviceVersion`, `attributes`, `headers` | Optional resource/transport metadata. |
|
|
156
197
|
|
|
157
|
-
|
|
198
|
+
Browser events batch every 30 seconds, up to 100 records by default. Override
|
|
199
|
+
`exportInterval`, `maxBatchSize`, and `shutdownTimeout` under `events`.
|
|
158
200
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
201
|
+
### Server events and shared options
|
|
202
|
+
|
|
203
|
+
Define server events as Effects and run them inside the runtime with
|
|
204
|
+
`ServerOtlp.layer` (or the HTTP layer):
|
|
162
205
|
|
|
163
206
|
```ts
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
});
|
|
169
|
-
yield* BrowserOtlp.track("app.checkout.started");
|
|
170
|
-
yield* BrowserOtlp.page({ path: "/checkout" });
|
|
171
|
-
yield* BrowserOtlp.identify(null);
|
|
207
|
+
import { Effect } from "effect";
|
|
208
|
+
import { ServerOtlp } from "@krak-stack/registry/opentelemetry/server";
|
|
209
|
+
|
|
210
|
+
const orderCompleted = Effect.gen(function* () {
|
|
211
|
+
yield* ServerOtlp.track("app.order.completed", { "order.total": 49 });
|
|
172
212
|
});
|
|
173
213
|
```
|
|
174
214
|
|
|
175
|
-
|
|
176
|
-
`
|
|
177
|
-
|
|
178
|
-
`identify` replaces the complete identity; omitting an organization clears the
|
|
179
|
-
previous organization. It emits no event. Identity is copied into each future
|
|
180
|
-
event when recorded; changes and resets do not rewrite queued events. Identified
|
|
181
|
-
user/org attributes override per-call properties/options, while scoped log
|
|
182
|
-
annotations take precedence over identified identity. This applies only to event
|
|
183
|
-
telemetry, not automatic trace/log exporters, API request headers, or authorization.
|
|
184
|
-
Browser identity is client-supplied and untrusted; use trusted server events for
|
|
185
|
-
billing, authorization, audit trails, or tenant-isolated reporting. Re-identify
|
|
186
|
-
after a reload and update identity before recording events after an auth or
|
|
187
|
-
organization change. The OTLP proxy remains passthrough and never enriches identity.
|
|
188
|
-
|
|
189
|
-
Initialize the browser layer once on the application's long-lived runtime. After
|
|
190
|
-
it starts, `Effect.runPromise(BrowserOtlp.identify(...))` and
|
|
191
|
-
`Effect.runPromise(BrowserOtlp.track(...))` work from ordinary application code.
|
|
192
|
-
Event methods retain typed validation errors and the calling fiber's trace/log
|
|
193
|
-
context; `identify` handles validation failures internally.
|
|
194
|
-
Calls executed before startup or after disposal are no-ops; nothing is buffered.
|
|
195
|
-
If several browser layers are active, calls target the most recently started one;
|
|
196
|
-
use a single browser layer in normal applications. There is no analytics bridge,
|
|
197
|
-
React hook, or automatic identification.
|
|
198
|
-
|
|
199
|
-
### Event options
|
|
200
|
-
|
|
201
|
-
Both environments accept
|
|
202
|
-
`track(name, properties?, options?)`. Common options are explicit and per-call,
|
|
203
|
-
so server requests never share mutable visitor state:
|
|
215
|
+
Authenticated handlers inherit `user.id` and `organization.id` from
|
|
216
|
+
`AuthMiddleware` log annotations. Server identity is fiber-scoped; there is no
|
|
217
|
+
server `identify` method. Background jobs can supply identity per event.
|
|
204
218
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
Both `track` methods accept `options`:
|
|
220
|
+
|
|
221
|
+
| Option | OTLP attribute / meaning |
|
|
222
|
+
| ------------------------------------------------- | ------------------------------------------------------------------- |
|
|
223
|
+
| `userId`, `anonymousId`, `sessionId`, `messageId` | `user.id`, `analytics.anonymous_id`, `session.id`, `log.record.uid` |
|
|
224
|
+
| `context` | Additional flat attributes |
|
|
225
|
+
| `timestamp` | Effect `DateTime.Utc` occurrence time; otherwise recorded now |
|
|
226
|
+
|
|
227
|
+
Attribute precedence, lowest to highest: context, properties, explicit identity
|
|
228
|
+
options, browser identified identity, scoped log annotations. Values support
|
|
229
|
+
strings, finite numbers, booleans, and homogeneous arrays, not nested objects.
|
|
230
|
+
Use stable event names and put dynamic values in attributes. Message IDs support
|
|
231
|
+
correlation, not guaranteed deduplication.
|
|
232
|
+
|
|
233
|
+
Events are OTLP log records with `eventName`, INFO severity, and active trace/span
|
|
234
|
+
IDs when available; they do not create spans. `browser.page_view`, `url.path`,
|
|
235
|
+
`analytics.page.name`, and `analytics.page.category` describe page events; the
|
|
236
|
+
analytics names are project conventions, not standardized OTel semantics.
|
|
237
|
+
|
|
238
|
+
Configure collector/storage separately. Browser identity is untrusted analytics
|
|
239
|
+
metadata, not authorization or an audit trail. No visitor/session IDs or cookies
|
|
240
|
+
are generated. Browser flushing on hidden/pagehide is best-effort. Apply payload
|
|
241
|
+
and rate limits at ingestion, and keep sensitive data out of events and
|
|
242
|
+
high-cardinality fields out of Loki labels.
|
|
218
243
|
|
|
219
|
-
|
|
220
|
-
context on collision. Options `userId`, `anonymousId`, `sessionId`, and `messageId`
|
|
221
|
-
map to `user.id`, `analytics.anonymous_id`, `session.id`, and `log.record.uid`,
|
|
222
|
-
overriding properties with the same keys. Scoped `Effect.annotateLogs` annotations
|
|
223
|
-
are inherited automatically and take precedence over all per-call attributes.
|
|
224
|
-
In authenticated server handlers, `AuthMiddleware` already supplies `user.id` and
|
|
225
|
-
`organization.id`, so do not repeat them in `.track()` calls. Background jobs and
|
|
226
|
-
browser code can provide identity explicitly when needed. Annotations remain
|
|
227
|
-
fiber-scoped; no identity state is persisted by the event service.
|
|
228
|
-
Identifiers are optional; callers own
|
|
229
|
-
consent and identity lifecycle. Message IDs aid correlation, not guaranteed
|
|
230
|
-
deduplication. Optional `timestamp` accepts an Effect `DateTime.Utc` for delayed
|
|
231
|
-
events; the SDK still sets observed time to the time of recording. There is no
|
|
232
|
-
clock-skew correction. `page` accepts `properties` and these same `options`, plus
|
|
233
|
-
optional `name` and `category` mapped to application-defined
|
|
234
|
-
`analytics.page.name` and `analytics.page.category` attributes. It always owns
|
|
235
|
-
the sanitized `url.path`. The `analytics.*` fields and `browser.page_view` name
|
|
236
|
-
are project conventions, not standardized OpenTelemetry analytics semantics.
|
|
237
|
-
Group, Alias, profile storage, destination routing, and automatic
|
|
238
|
-
collection of IPs, user agents, page titles, referrers, and full URLs are not
|
|
239
|
-
implemented.
|
|
240
|
-
|
|
241
|
-
Both `.track(name, attributes?)` methods follow the
|
|
242
|
-
[OpenTelemetry event conventions](https://opentelemetry.io/docs/specs/semconv/general/events/):
|
|
243
|
-
records have the native `eventName` field, an occurrence timestamp, INFO severity
|
|
244
|
-
number (9), flat structured attributes, and no body. The SDK sets observed time
|
|
245
|
-
when it records the occurrence. Events inherit active trace/span IDs without
|
|
246
|
-
creating spans. Use stable domain-qualified names with no dynamic identifiers;
|
|
247
|
-
put changing values in attributes. Document each custom event's trigger and
|
|
248
|
-
required/optional attributes; include `error.type` for failures. These conventions
|
|
249
|
-
are still in development. Attribute values support strings, finite numbers,
|
|
250
|
-
booleans, and homogeneous arrays of those values. Invalid inputs fail with an
|
|
251
|
-
Effect schema error.
|
|
252
|
-
|
|
253
|
-
The logs proxy must be enabled with `OTEL_LOGS_EXPORTER=otlp` for browser events.
|
|
254
|
-
OTLP transports events; configure a collector and a logs backend such as Loki for
|
|
255
|
-
storage and Grafana dashboards. Browser flushing on hidden/pagehide is best
|
|
256
|
-
effort. Apply payload limits and rate limits at your public ingestion boundary,
|
|
257
|
-
avoid sensitive attributes, and keep high-cardinality fields out of Loki labels.
|
|
244
|
+
## Other services
|
|
258
245
|
|
|
259
246
|
`@krak-stack/registry/service-notification` is the source-compatible direct
|
|
260
247
|
dispatcher. Use the separate `@krak-stack/notifications` package for a durable
|
|
@@ -1339,9 +1339,7 @@ var uiFromState = (state) => ({
|
|
|
1339
1339
|
var sameUiState = (left, right) => left.columnVisibility === right.columnVisibility && left.columnSizing === right.columnSizing && left.rowSelection === right.rowSelection && left.grouping === right.grouping && left.collapsedGroups === right.collapsedGroups && left.view === right.view;
|
|
1340
1340
|
var sameQueryState = (left, right) => left.page === right.page && left.pageSize === right.pageSize && left.globalFilter === right.globalFilter && left.sort === right.sort;
|
|
1341
1341
|
var initialPublicState = (props, uiState) => ({
|
|
1342
|
-
...DEFAULT_QUERY,
|
|
1343
|
-
...props.initialState,
|
|
1344
|
-
...props.state,
|
|
1342
|
+
...queryFromState(props.state ?? { ...DEFAULT_QUERY, ...props.initialState }),
|
|
1345
1343
|
...uiState
|
|
1346
1344
|
});
|
|
1347
1345
|
var buildDataTableModel = (store) => {
|
|
@@ -1378,7 +1376,7 @@ var changeState = (setStore, update) => {
|
|
|
1378
1376
|
if (!sameUiState(uiState, store.state)) {
|
|
1379
1377
|
store.config.onUiStateChange(uiState);
|
|
1380
1378
|
}
|
|
1381
|
-
const state = store.controlledState ? { ...proposed, ...store.controlledState } : proposed;
|
|
1379
|
+
const state = store.controlledState ? { ...proposed, ...queryFromState(store.controlledState) } : proposed;
|
|
1382
1380
|
if (sameDataTableState(state, store.state))
|
|
1383
1381
|
return store;
|
|
1384
1382
|
const next = { ...store, state };
|
|
@@ -1700,7 +1698,7 @@ var DataTableToolbar = ({
|
|
|
1700
1698
|
}),
|
|
1701
1699
|
store.state.globalFilter ? /* @__PURE__ */ jsx14(Button, {
|
|
1702
1700
|
"aria-label": labels.filter,
|
|
1703
|
-
className: "absolute top-1/2 right-1 size-7 -translate-y-1/2",
|
|
1701
|
+
className: "absolute top-1/2 right-1 size-7 -translate-y-1/2 active:not-aria-[haspopup]:-translate-y-1/2",
|
|
1704
1702
|
onClick: () => update((state) => ({
|
|
1705
1703
|
...state,
|
|
1706
1704
|
globalFilter: undefined,
|
|
@@ -2887,7 +2885,11 @@ var HydratedDataTable = ({
|
|
|
2887
2885
|
labels: dataTableMessages(props.locale, props.messages),
|
|
2888
2886
|
locale: props.locale ?? "en"
|
|
2889
2887
|
};
|
|
2890
|
-
const state = {
|
|
2888
|
+
const state = {
|
|
2889
|
+
...store.state,
|
|
2890
|
+
...uiState,
|
|
2891
|
+
...queryFromState(props.state ?? store.state)
|
|
2892
|
+
};
|
|
2891
2893
|
const modelChanged = store.rowData !== props.rowData || store.columnDefs !== props.columnDefs || !sameDataTableState(store.state, state) || store.config.getRowId !== config.getRowId || store.config.features.pagination !== config.features.pagination;
|
|
2892
2894
|
const next = {
|
|
2893
2895
|
...store,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@krak-stack/registry",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"description": "Tree-shakable KrakStack components and Effect services.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
13
13
|
"README.md",
|
|
14
|
-
"patches",
|
|
15
14
|
"tailwind.css"
|
|
16
15
|
],
|
|
17
16
|
"type": "module",
|
|
@@ -241,8 +240,8 @@
|
|
|
241
240
|
"@effect/platform-browser": "^4.0.0",
|
|
242
241
|
"@iconify/react": "^6.0.2",
|
|
243
242
|
"@inlang/paraglide-js": "^2.19.0",
|
|
244
|
-
"@lucas-barake/effect-form": "
|
|
245
|
-
"@lucas-barake/effect-form-react": "
|
|
243
|
+
"@lucas-barake/effect-form": "1.1.0",
|
|
244
|
+
"@lucas-barake/effect-form-react": "1.1.0",
|
|
246
245
|
"@tanstack/highlight": "^0.0.10",
|
|
247
246
|
"@tanstack/react-form": "^1.33.0",
|
|
248
247
|
"@tanstack/react-router": "^1.170.15",
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
diff --git a/dist/FormReact.d.ts b/dist/FormReact.d.ts
|
|
2
|
-
index 61b65ad3ef858a3d9994d4cfde7e47216d44b549..0431a57a4a27eefa43180fc19f04f887a25ebf24 100644
|
|
3
|
-
--- a/dist/FormReact.d.ts
|
|
4
|
-
+++ b/dist/FormReact.d.ts
|
|
5
|
-
@@ -4,8 +4,8 @@ import type * as FormBuilder from "@lucas-barake/effect-form/FormBuilder";
|
|
6
|
-
import type * as Effect from "effect/Effect";
|
|
7
|
-
import * as Option from "effect/Option";
|
|
8
|
-
import type * as Schema from "effect/Schema";
|
|
9
|
-
-import * as Atom from "effect/unstable/reactivity/Atom";
|
|
10
|
-
-import type * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
|
|
11
|
-
+import * as Atom from "effect/reactivity/Atom";
|
|
12
|
-
+import type * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
13
|
-
import * as React from "react";
|
|
14
|
-
export type FieldValue<T> = FieldStateModule.FieldValue<T>;
|
|
15
|
-
export type FieldState<E> = FieldStateModule.FieldState<E>;
|
|
16
|
-
diff --git a/dist/FormReact.js b/dist/FormReact.js
|
|
17
|
-
index 03e34ec60b833b4dd220ac6faffe70b9138703cd..f313c18c5e6cdb7138e19180aeb0acd4281857fa 100644
|
|
18
|
-
--- a/dist/FormReact.js
|
|
19
|
-
+++ b/dist/FormReact.js
|
|
20
|
-
@@ -4,7 +4,7 @@ import { Field, FormAtoms } from "@lucas-barake/effect-form";
|
|
21
|
-
import { getNestedValue } from "@lucas-barake/effect-form/Path";
|
|
22
|
-
import * as Layer from "effect/Layer";
|
|
23
|
-
import * as Option from "effect/Option";
|
|
24
|
-
-import * as Atom from "effect/unstable/reactivity/Atom";
|
|
25
|
-
+import * as Atom from "effect/reactivity/Atom";
|
|
26
|
-
import * as React from "react";
|
|
27
|
-
import { createContext, useContext } from "react";
|
|
28
|
-
const ArrayItemContext = /*#__PURE__*/createContext(null);
|
|
29
|
-
diff --git a/package.json b/package.json
|
|
30
|
-
index 416aed4983dfb7dfc1528b3cca636b860ab0986e..048e49b01201623854c1c8f042044d3f5bd64703 100644
|
|
31
|
-
--- a/package.json
|
|
32
|
-
+++ b/package.json
|
|
33
|
-
@@ -41,14 +41,14 @@
|
|
34
|
-
"@lucas-barake/effect-form": "^0.25.0-beta.6"
|
|
35
|
-
},
|
|
36
|
-
"devDependencies": {
|
|
37
|
-
- "@effect/atom-react": "4.0.0-beta.52",
|
|
38
|
-
+ "@effect/atom-react": "4.0.0",
|
|
39
|
-
"@vitejs/plugin-react": "^5.1.1",
|
|
40
|
-
- "effect": "4.0.0-beta.52",
|
|
41
|
-
+ "effect": "4.0.0",
|
|
42
|
-
"react": "^19.0.0"
|
|
43
|
-
},
|
|
44
|
-
"peerDependencies": {
|
|
45
|
-
- "@effect/atom-react": ">=4.0.0-beta.52 <4.0.1",
|
|
46
|
-
- "effect": ">=4.0.0-beta.52 <4.0.1",
|
|
47
|
-
+ "@effect/atom-react": "^4.0.0",
|
|
48
|
-
+ "effect": "^4.0.0",
|
|
49
|
-
"react": "^19.0.0"
|
|
50
|
-
},
|
|
51
|
-
"scripts": {
|
|
52
|
-
diff --git a/src/FormReact.tsx b/src/FormReact.tsx
|
|
53
|
-
index 49c358e92fe04a62a9ef97dbae6665ce53e905a5..dfb2792d4b824d448bf3e8f4b469c0861422bd6f 100644
|
|
54
|
-
--- a/src/FormReact.tsx
|
|
55
|
-
+++ b/src/FormReact.tsx
|
|
56
|
-
@@ -7,8 +7,8 @@ import type * as Effect from "effect/Effect"
|
|
57
|
-
import * as Layer from "effect/Layer"
|
|
58
|
-
import * as Option from "effect/Option"
|
|
59
|
-
import type * as Schema from "effect/Schema"
|
|
60
|
-
-import * as Atom from "effect/unstable/reactivity/Atom"
|
|
61
|
-
-import type * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
|
62
|
-
+import * as Atom from "effect/reactivity/Atom"
|
|
63
|
-
+import type * as AtomRegistry from "effect/reactivity/AtomRegistry"
|
|
64
|
-
import * as React from "react"
|
|
65
|
-
import { createContext, useContext } from "react"
|
|
66
|
-
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
diff --git a/dist/FormAtoms.d.ts b/dist/FormAtoms.d.ts
|
|
2
|
-
index 08d1e4e2e8edf08cecb5b550099c3293cbd10cd7..f7b1fa4a5a7d65e8b8b3785dc9eb5397d24718b4 100644
|
|
3
|
-
--- a/dist/FormAtoms.d.ts
|
|
4
|
-
+++ b/dist/FormAtoms.d.ts
|
|
5
|
-
@@ -1,7 +1,7 @@
|
|
6
|
-
import * as Effect from "effect/Effect";
|
|
7
|
-
import * as Option from "effect/Option";
|
|
8
|
-
import * as Schema from "effect/Schema";
|
|
9
|
-
-import * as Atom from "effect/unstable/reactivity/Atom";
|
|
10
|
-
+import * as Atom from "effect/reactivity/Atom";
|
|
11
|
-
import * as Field from "./Field.ts";
|
|
12
|
-
import * as FormBuilder from "./FormBuilder.ts";
|
|
13
|
-
import * as Mode from "./Mode.ts";
|
|
14
|
-
diff --git a/dist/FormAtoms.js b/dist/FormAtoms.js
|
|
15
|
-
index 663c4478a08eb17bfb7a11df952ced8f7812cbf8..ebaa1be93c33af0390857e945a9d414094f215ab 100644
|
|
16
|
-
--- a/dist/FormAtoms.js
|
|
17
|
-
+++ b/dist/FormAtoms.js
|
|
18
|
-
@@ -3,8 +3,8 @@ import * as Effect from "effect/Effect";
|
|
19
|
-
import { pipe } from "effect/Function";
|
|
20
|
-
import * as Option from "effect/Option";
|
|
21
|
-
import * as Schema from "effect/Schema";
|
|
22
|
-
-import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
|
|
23
|
-
-import * as Atom from "effect/unstable/reactivity/Atom";
|
|
24
|
-
+import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
25
|
-
+import * as Atom from "effect/reactivity/Atom";
|
|
26
|
-
import * as Field from "./Field.js";
|
|
27
|
-
import * as FormBuilder from "./FormBuilder.js";
|
|
28
|
-
import { recalculateDirtyFieldsForArray, recalculateDirtySubtree } from "./internal/dirty.js";
|
|
29
|
-
diff --git a/dist/FormBuilder.d.ts b/dist/FormBuilder.d.ts
|
|
30
|
-
index d42cf00d24b9efea5168831549b85468a64dfcef..16dfc1af6443555454ec7e6219c94eeabce3d724 100644
|
|
31
|
-
--- a/dist/FormBuilder.d.ts
|
|
32
|
-
+++ b/dist/FormBuilder.d.ts
|
|
33
|
-
@@ -1,7 +1,7 @@
|
|
34
|
-
import type * as Effect from "effect/Effect";
|
|
35
|
-
import type * as Option from "effect/Option";
|
|
36
|
-
import * as Schema from "effect/Schema";
|
|
37
|
-
-import type * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
|
|
38
|
-
+import type * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
39
|
-
import type { ArrayFieldDef, DecodedFromFields, EncodedFromFields, FieldDef, FieldsRecord } from "./Field.ts";
|
|
40
|
-
/**
|
|
41
|
-
* Flattens an intersection of field records into a single object type so that
|
|
42
|
-
diff --git a/package.json b/package.json
|
|
43
|
-
index 96ad0aa1729c64e8378a8cb2ad29f13b5347e568..06ae5ac6312779be749ff867b846c8f3c4ccf5b1 100644
|
|
44
|
-
--- a/package.json
|
|
45
|
-
+++ b/package.json
|
|
46
|
-
@@ -36,10 +36,10 @@
|
|
47
|
-
"license": "MIT",
|
|
48
|
-
"sideEffects": [],
|
|
49
|
-
"peerDependencies": {
|
|
50
|
-
- "effect": ">=4.0.0-beta.52 <4.0.1"
|
|
51
|
-
+ "effect": "^4.0.0"
|
|
52
|
-
},
|
|
53
|
-
"devDependencies": {
|
|
54
|
-
- "effect": "4.0.0-beta.52"
|
|
55
|
-
+ "effect": "4.0.0"
|
|
56
|
-
},
|
|
57
|
-
"scripts": {
|
|
58
|
-
"build": "tsc -b tsconfig.json && pnpm babel",
|
|
59
|
-
diff --git a/src/FormAtoms.ts b/src/FormAtoms.ts
|
|
60
|
-
index bc60a7f7b676edf4d1e99f6eb4162335b3247022..60d3dadfe2ef14c0a1b66b5e16886e8870c82681 100644
|
|
61
|
-
--- a/src/FormAtoms.ts
|
|
62
|
-
+++ b/src/FormAtoms.ts
|
|
63
|
-
@@ -3,8 +3,8 @@ import * as Effect from "effect/Effect"
|
|
64
|
-
import { pipe } from "effect/Function"
|
|
65
|
-
import * as Option from "effect/Option"
|
|
66
|
-
import * as Schema from "effect/Schema"
|
|
67
|
-
-import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
68
|
-
-import * as Atom from "effect/unstable/reactivity/Atom"
|
|
69
|
-
+import * as AsyncResult from "effect/reactivity/AsyncResult"
|
|
70
|
-
+import * as Atom from "effect/reactivity/Atom"
|
|
71
|
-
import * as Field from "./Field.ts"
|
|
72
|
-
import * as FormBuilder from "./FormBuilder.ts"
|
|
73
|
-
import { recalculateDirtyFieldsForArray, recalculateDirtySubtree } from "./internal/dirty.ts"
|
|
74
|
-
diff --git a/src/FormBuilder.ts b/src/FormBuilder.ts
|
|
75
|
-
index 764de854be6b072967d1140c707ba9565eda9516..6a2d0fe285ae3b2d1afc4bf928897e5b7bfb0a4b 100644
|
|
76
|
-
--- a/src/FormBuilder.ts
|
|
77
|
-
+++ b/src/FormBuilder.ts
|
|
78
|
-
@@ -3,7 +3,7 @@ import type * as Option from "effect/Option"
|
|
79
|
-
import * as Predicate from "effect/Predicate"
|
|
80
|
-
import * as Schema from "effect/Schema"
|
|
81
|
-
import * as SchemaGetter from "effect/SchemaGetter"
|
|
82
|
-
-import type * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
|
83
|
-
+import type * as AtomRegistry from "effect/reactivity/AtomRegistry"
|
|
84
|
-
|
|
85
|
-
import type {
|
|
86
|
-
AnyFieldDef,
|
package/patches/README.md
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# Temporary Effect form compatibility patches
|
|
2
|
-
|
|
3
|
-
These patches backport the stable Effect 4 changes from upstream commit
|
|
4
|
-
[`c10a53e041c9b0b338b26b2af66be5eb24f07d47`](https://github.com/lucas-barake/effect-form/commit/c10a53e041c9b0b338b26b2af66be5eb24f07d47).
|
|
5
|
-
The fixed npm packages are awaiting [release PR #111](https://github.com/lucas-barake/effect-form/pull/111).
|
|
6
|
-
|
|
7
|
-
The patches update reactivity imports in shipped JavaScript, TypeScript
|
|
8
|
-
declarations, and source, and change Effect peer ranges to `^4.0.0`.
|
|
9
|
-
They do not change form behavior or package versions.
|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
The workspace-root `package.json` configures `patchedDependencies` and exact
|
|
14
|
-
version overrides for both packages. Run `bun install` to apply them; commit
|
|
15
|
-
these patch files, `package.json`, and `bun.lock` together. In a monorepo, configure
|
|
16
|
-
the patches at the workspace root, not inside individual packages.
|
|
17
|
-
|
|
18
|
-
Patches do **not** propagate from a published KrakStack package to a consuming
|
|
19
|
-
application. Every application using the affected form packages must configure
|
|
20
|
-
both patches itself. The interim Auth and Registry packages also ship copies
|
|
21
|
-
under `patches/` for consumers to copy into their application roots.
|
|
22
|
-
|
|
23
|
-
## Removing the workaround
|
|
24
|
-
|
|
25
|
-
After upstream publishes `@lucas-barake/effect-form@0.25.0-beta.7` and
|
|
26
|
-
`@lucas-barake/effect-form-react@0.26.0-beta.6` (or newer compatible releases):
|
|
27
|
-
|
|
28
|
-
1. Update direct dependencies and KrakStack peer requirements to the fixed versions.
|
|
29
|
-
2. Remove the two form overrides and `patchedDependencies` entries.
|
|
30
|
-
3. Remove these two patch files and any copies shipped with KrakStack packages.
|
|
31
|
-
4. Run `bun install`, then the project's type, test, and release checks.
|