cogsbox-shape 0.5.217 → 0.5.219

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.
@@ -68,6 +68,8 @@ type ShapeKeyValidationParams = {
68
68
  path: string[];
69
69
  keys?: readonly string[];
70
70
  getState?: () => unknown;
71
+ /** When true (default), writes filtered issues to shadow validation metadata. */
72
+ persist?: boolean;
71
73
  };
72
74
  export declare function wireShapeValidationOptions(box: ShapeSchemaBox, params: TransformStateParams): void;
73
75
  /** Cross-field refine errors only — field rules are handled by state via setOptions. */
@@ -117,30 +117,79 @@ function addValidationIssues(params, issues) {
117
117
  params.addZodErrors(issues);
118
118
  notifyValidationPaths(params.stateKey, issues.map((issue) => issue.path));
119
119
  }
120
- function setValidationIssues(stateKey, issues) {
121
- if (issues.length === 0)
122
- return;
120
+ function createShadowValidationBridge(stateKey) {
123
121
  const store = getGlobalStore.getState();
124
- for (const issue of issues) {
125
- const currentMeta = store.getShadowMetadata(stateKey, issue.path) || {};
126
- store.setShadowMetadata(stateKey, issue.path, {
127
- ...currentMeta,
128
- validation: {
129
- status: "INVALID",
130
- errors: [
131
- {
132
- source: "client",
133
- message: issue.message,
134
- severity: "error",
135
- code: issue.code,
122
+ return {
123
+ stateKey,
124
+ getState: () => store.getShadowValue(stateKey, []),
125
+ addZodErrors: (issues) => {
126
+ for (const error of issues) {
127
+ const errorPath = error.path;
128
+ const currentMeta = store.getShadowMetadata(stateKey, errorPath) || {};
129
+ store.setShadowMetadata(stateKey, errorPath, {
130
+ ...currentMeta,
131
+ validation: {
132
+ status: "INVALID",
133
+ errors: [
134
+ {
135
+ source: "client",
136
+ message: error.message,
137
+ severity: "error",
138
+ code: error.code,
139
+ },
140
+ ],
141
+ lastValidated: Date.now(),
142
+ validatedValue: undefined,
136
143
  },
137
- ],
138
- lastValidated: Date.now(),
139
- validatedValue: store.getShadowValue(stateKey, issue.path),
140
- },
141
- });
144
+ });
145
+ }
146
+ },
147
+ clearZodErrors: (paths) => {
148
+ for (const path of paths) {
149
+ const currentMeta = store.getShadowMetadata(stateKey, path) || {};
150
+ store.setShadowMetadata(stateKey, path, {
151
+ ...currentMeta,
152
+ validation: {
153
+ status: "NOT_VALIDATED",
154
+ errors: [],
155
+ lastValidated: Date.now(),
156
+ validatedValue: undefined,
157
+ },
158
+ });
159
+ }
160
+ },
161
+ };
162
+ }
163
+ function notifyStateComponents(stateKey) {
164
+ const store = getGlobalStore.getState();
165
+ const stateEntry = store.getShadowMetadata(stateKey, []);
166
+ if (!stateEntry?.components)
167
+ return;
168
+ const updates = new Set();
169
+ stateEntry.components.forEach((component) => {
170
+ const reactiveTypes = component
171
+ ? Array.isArray(component.reactiveType)
172
+ ? component.reactiveType
173
+ : [component.reactiveType || "component"]
174
+ : null;
175
+ if (!reactiveTypes?.includes("none")) {
176
+ updates.add(() => component.forceUpdate());
177
+ }
178
+ });
179
+ queueMicrotask(() => {
180
+ updates.forEach((update) => update());
181
+ });
182
+ }
183
+ function persistValidateGroupResults(params, keys, mapped) {
184
+ const validationParams = createShadowValidationBridge(params.stateKey);
185
+ const keyPaths = keys.map((key) => [...params.path, key]);
186
+ const activeKeys = new Set(mapped.map((issue) => pathKey(issue.path)));
187
+ const stalePaths = keyPaths.filter((targetPath) => !activeKeys.has(pathKey(targetPath)));
188
+ clearValidationPaths(validationParams, stalePaths);
189
+ if (mapped.length > 0) {
190
+ addValidationIssues(validationParams, mapped);
142
191
  }
143
- notifyValidationPaths(stateKey, issues.map((issue) => issue.path));
192
+ notifyStateComponents(params.stateKey);
144
193
  }
145
194
  function issueMatchesSelectedKeys(issue, parentPath, selectedKeys) {
146
195
  const issuePath = issue.path.map(String);
@@ -285,20 +334,14 @@ export function validateShapeKeys(box, params) {
285
334
  const clientSchema = entry?.validators?.client ?? entry?.schemas.client;
286
335
  if (!entry || !clientSchema)
287
336
  return { success: true, results: [] };
288
- const store = getGlobalStore.getState();
289
- const rootState = params.getState?.() ?? store.getShadowValue(params.stateKey, []);
337
+ const rootState = params.getState?.() ?? getGlobalStore.getState().getShadowValue(params.stateKey, []);
290
338
  const result = clientSchema.safeParse(rootState);
291
339
  const selectedKeys = params.keys ? new Set(params.keys) : null;
292
- const targetPaths = params.keys?.map((key) => [...params.path, key]) ??
293
- (result.success
294
- ? []
295
- : mapZodIssues(result.error.issues).map((issue) => issue.path));
340
+ const shouldPersist = params.persist !== false && !!params.keys?.length;
296
341
  if (result.success) {
297
- clearValidationPaths({
298
- stateKey: params.stateKey,
299
- getState: () => rootState,
300
- addZodErrors: () => { },
301
- }, targetPaths);
342
+ if (shouldPersist) {
343
+ persistValidateGroupResults(params, params.keys, []);
344
+ }
302
345
  return {
303
346
  success: true,
304
347
  results: params.keys?.map((key) => ({
@@ -313,14 +356,9 @@ export function validateShapeKeys(box, params) {
313
356
  ? result.error.issues.filter((issue) => issueMatchesSelectedKeys(issue, params.path, selectedKeys))
314
357
  : result.error.issues;
315
358
  const mapped = mapZodIssues(issues);
316
- const activeKeys = new Set(mapped.map((issue) => pathKey(issue.path)));
317
- const stalePaths = targetPaths.filter((targetPath) => !activeKeys.has(pathKey(targetPath)));
318
- clearValidationPaths({
319
- stateKey: params.stateKey,
320
- getState: () => rootState,
321
- addZodErrors: () => { },
322
- }, stalePaths);
323
- setValidationIssues(params.stateKey, mapped);
359
+ if (shouldPersist) {
360
+ persistValidateGroupResults(params, params.keys, mapped);
361
+ }
324
362
  return {
325
363
  success: mapped.length === 0,
326
364
  results: params.keys?.map((key) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-shape",
3
- "version": "0.5.217",
3
+ "version": "0.5.219",
4
4
  "description": "A TypeScript library for creating type-safe database schemas with Zod validation, SQL type definitions, and automatic client/server transformations. Unifies client, server, and database types through a single schema definition, with built-in support for relationships and serialization.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",