@vxil/sdk 0.12.0 → 0.13.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/index.d.ts CHANGED
@@ -1999,6 +1999,12 @@ export interface CmsReindexPage {
1999
1999
  skipped: number;
2000
2000
  next_cursor: string | null;
2001
2001
  complete: boolean;
2002
+ /** Present when this page certified an index (the last page of a pass over
2003
+ * a collection whose equality / owner index was not armed): 'armed',
2004
+ * 'pending' (rows changed during the pass — run another) or 'timeout' (the
2005
+ * check ran out of time — the index stays unarmed; filters stay correct
2006
+ * but unaccelerated). */
2007
+ index_certify?: 'armed' | 'pending' | 'timeout';
2002
2008
  }
2003
2009
  /** The result of a bounded filtered delete (cms.md §20). `matched` counts the
2004
2010
  * rows this page selected (≤ `limit`); `deleted` counts the ones actually
@@ -3569,6 +3575,12 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3569
3575
  * session) still sees every field. Writes are unaffected. ≤16 entries,
3570
3576
  * each `^[a-z0-9][a-z0-9_-]{0,31}$` (the `orgs` role alphabet). */
3571
3577
  read_roles?: string[];
3578
+ /** Equality index for an UNSLOTTED field (cms.md §3 "Indexed
3579
+ * equality"): `=` / `$eq` / `$in` filters on it are index-served
3580
+ * instead of a bounded scan — results are identical either way. ≤4
3581
+ * per collection; not with `index_slot` (a slot already indexes
3582
+ * equality) and not on a computed field. */
3583
+ indexed?: boolean;
3572
3584
  }>;
3573
3585
  /** Per-record action buttons (cms.md §17): `[{ key, label, fn }]` —
3574
3586
  * exactly ONE human-initiated step each; `fn` names a deployed tenant
@@ -3596,6 +3608,18 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3596
3608
  * read unless the session's verified roles intersect `roles`; server-caller
3597
3609
  * reads and ALL writes are unaffected. */
3598
3610
  setFieldReadRoles: (collection: string, field: string, type: "string" | "text" | "int" | "float" | "bool" | "datetime" | "json" | "relation" | "file", roles: string[] | null, rest?: Record<string, unknown>) => Promise<void>;
3611
+ /** Turn a field's EQUALITY INDEX on or off (cms.md §3 "Indexed equality")
3612
+ * — the same-type in-place alter on the fields route; `indexed` is
3613
+ * present-key, so no other attribute moves. Only for UNSLOTTED,
3614
+ * non-computed fields, ≤4 per collection (422 `eq_index_budget`).
3615
+ * `index_ready: false` + `reindex_required: true` on a collection over
3616
+ * 2,000 live items: run `reindexAll` (until then filters stay on the
3617
+ * bounded scan — never wrong, only slower). */
3618
+ setFieldIndexed: (collection: string, field: string, type: "string" | "text" | "int" | "float" | "bool" | "datetime" | "json" | "relation" | "file", indexed: boolean) => Promise<{
3619
+ indexed: boolean;
3620
+ index_ready: boolean;
3621
+ reindex_required: boolean;
3622
+ }>;
3599
3623
  /** Set (or clear, with `null`) the collection's end-user owner-scope flag
3600
3624
  * (design §5.1). Names an existing `string` field that holds the owner id. */
3601
3625
  setOwnerField: (collection: string, ownerField: string | null) => Promise<void>;
@@ -3633,6 +3657,7 @@ export declare class Vxil<S extends VxilSchemaShape = VxilSchemaShape> {
3633
3657
  updated: number;
3634
3658
  skipped: number;
3635
3659
  pages: number;
3660
+ index_certify?: CmsReindexPage["index_certify"];
3636
3661
  }>;
3637
3662
  /** Replace the collection's per-record ACTION list (cms.md §17) — the
3638
3663
  * `{ actions }` fields-route meta-op; `[]` clears. Each action is ONE
package/dist/index.js CHANGED
@@ -1088,6 +1088,29 @@ export class Vxil {
1088
1088
  setFieldReadRoles: async (collection, field, type, roles, rest = {}) => {
1089
1089
  await this.call('POST', `/v1/cms/collections/${encodeURIComponent(collection)}/fields`, { ...rest, field, type, read_roles: roles ?? [] });
1090
1090
  },
1091
+ /** Turn a field's EQUALITY INDEX on or off (cms.md §3 "Indexed equality")
1092
+ * — the same-type in-place alter on the fields route; `indexed` is
1093
+ * present-key, so no other attribute moves. Only for UNSLOTTED,
1094
+ * non-computed fields, ≤4 per collection (422 `eq_index_budget`).
1095
+ * `index_ready: false` + `reindex_required: true` on a collection over
1096
+ * 2,000 live items: run `reindexAll` (until then filters stay on the
1097
+ * bounded scan — never wrong, only slower). */
1098
+ setFieldIndexed: async (collection, field, type, indexed) => {
1099
+ try {
1100
+ const d = (await this.call('POST', `/v1/cms/collections/${encodeURIComponent(collection)}/fields`, { field, type, indexed })).data ?? {};
1101
+ return { indexed: d.indexed ?? indexed, index_ready: d.index_ready ?? indexed, reindex_required: d.reindex_required === true };
1102
+ }
1103
+ catch (e) {
1104
+ // 409 already_exists = the field is already in that state (the
1105
+ // idempotent re-POST); read its readiness from the collection list.
1106
+ if (!(e instanceof VxilError) || e.status !== 409)
1107
+ throw e;
1108
+ const colls = (await this.call('GET', '/v1/cms/collections')).data.collections;
1109
+ const f = colls.find((c) => c.collection === collection)?.fields.find((x) => x.field === field);
1110
+ const ready = f?.index_ready === true;
1111
+ return { indexed: f?.indexed === true, index_ready: ready, reindex_required: f?.indexed === true && !ready };
1112
+ }
1113
+ },
1091
1114
  /** Set (or clear, with `null`) the collection's end-user owner-scope flag
1092
1115
  * (design §5.1). Names an existing `string` field that holds the owner id. */
1093
1116
  setOwnerField: async (collection, ownerField) => {
@@ -1126,6 +1149,7 @@ export class Vxil {
1126
1149
  let updated = 0;
1127
1150
  let skipped = 0;
1128
1151
  let pages = 0;
1152
+ let indexCertify;
1129
1153
  for (;;) {
1130
1154
  let page = await this.cms.collections.reindex(collection, {
1131
1155
  ...(opts?.field ? { field: opts.field } : {}),
@@ -1148,11 +1172,13 @@ export class Vxil {
1148
1172
  opts?.onPage?.(page);
1149
1173
  }
1150
1174
  skipped += page.skipped ?? 0;
1175
+ if (page.index_certify)
1176
+ indexCertify = page.index_certify;
1151
1177
  if (page.complete || !page.next_cursor)
1152
1178
  break;
1153
1179
  cursor = page.next_cursor;
1154
1180
  }
1155
- return { scanned, updated, skipped, pages };
1181
+ return { scanned, updated, skipped, pages, ...(indexCertify ? { index_certify: indexCertify } : {}) };
1156
1182
  },
1157
1183
  /** Replace the collection's per-record ACTION list (cms.md §17) — the
1158
1184
  * `{ actions }` fields-route meta-op; `[]` clears. Each action is ONE
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vxil/sdk",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Typed client for the Vxil REST API (notifications, auth, jobs, files, cms, comments, webhooks, realtime, orgs, rate-limits).",