@ai-matrx/associations 0.8.11 → 0.9.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/CHANGELOG.md +49 -0
- package/README.md +5 -6
- package/dist/{CommentThread--C4Vgv0S.d.cts → CommentThread-BKDzEKvk.d.cts} +1 -1
- package/dist/{CommentThread--C4Vgv0S.d.ts → CommentThread-BKDzEKvk.d.ts} +1 -1
- package/dist/core/index.cjs +0 -165
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +1 -37
- package/dist/core/index.d.ts +1 -37
- package/dist/core/index.js +0 -165
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +0 -195
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +3 -12
- package/dist/react/index.d.ts +3 -12
- package/dist/react/index.js +21 -221
- package/dist/react/index.js.map +1 -1
- package/dist/react/lazy/index.d.cts +1 -1
- package/dist/react/lazy/index.d.ts +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/associations
|
|
2
2
|
|
|
3
|
+
## 0.9.0 — BREAKING: the boot probe is deleted
|
|
4
|
+
|
|
5
|
+
`AssociationsProvider` used to run `assertDemandedSchema` on mount. That probe
|
|
6
|
+
established whether each of the 26 demanded RPCs existed **by calling it** with
|
|
7
|
+
sentinel arguments — and **fourteen of them are writes** (`assoc_add`,
|
|
8
|
+
`assoc_set_targets`, `assoc_remove_for_entity`, `conversation_file_add`,
|
|
9
|
+
`agent_resource_add`, `cat_create`/`cat_update`/`cat_reparent`/`cat_delete`,
|
|
10
|
+
`ues_set`, `ues_touch`, `cmt_add`, `cmt_edit`, `cmt_delete`). Measured in the
|
|
11
|
+
AI Matrx frontend on `/administration/billing/spend`: **25 POSTs to
|
|
12
|
+
`/rest/v1/rpc/<name>` answered 400 on every page load**, ahead of the page's own
|
|
13
|
+
reads.
|
|
14
|
+
|
|
15
|
+
It was documented as dev-only. It was not. The gate was
|
|
16
|
+
`process.env.NODE_ENV === "development"`, and tsup builds this package with
|
|
17
|
+
`platform: "browser"`, where esbuild SUBSTITUTES that expression at build time —
|
|
18
|
+
the shipped `dist/react/index.js` read `typeof process !== "undefined" && true`.
|
|
19
|
+
Every consumer fired the storm in production.
|
|
20
|
+
|
|
21
|
+
**THE CLASS RULE: a write RPC is never invoked to ask whether it exists.**
|
|
22
|
+
|
|
23
|
+
Removed, not deprecated (a knob nobody can safely turn on is not a knob):
|
|
24
|
+
|
|
25
|
+
- `assertDemandedSchema`, `SELF_TEST_MISSING_RPC`, `AssertDemandedSchemaOptions`
|
|
26
|
+
and `DemandedSchemaReport` are gone from `@ai-matrx/associations/core`.
|
|
27
|
+
- The `probeSchema` prop is gone from `AssociationsProvider`.
|
|
28
|
+
- Mounting the provider now issues **no network call at all**.
|
|
29
|
+
|
|
30
|
+
Nothing replaces it, because nothing needs to. A database that cannot answer a
|
|
31
|
+
demanded function still says so, loudly, at the first REAL call: PostgREST
|
|
32
|
+
returns PGRST202 and `mapPgError` raises `demanded_schema_violation` with the
|
|
33
|
+
same remedy — at the moment it matters, and at zero cost on the loads where the
|
|
34
|
+
database is right.
|
|
35
|
+
|
|
36
|
+
Guards (both proven failing-then-passing):
|
|
37
|
+
`src/react/__tests__/mount-is-inert.test.tsx` — a recorder sees an RPC when one
|
|
38
|
+
is made (the self-test), and mounting the provider records none.
|
|
39
|
+
`src/__tests__/no-node-env-gating.test.ts` — no source file reads `NODE_ENV` in
|
|
40
|
+
code, because our own build bakes it. `scripts/verify-tarball.mjs` asserts the
|
|
41
|
+
SHIPPED cjs core no longer exports `assertDemandedSchema`.
|
|
42
|
+
|
|
43
|
+
**Consumer action.** Delete any `probeSchema` prop you pass to
|
|
44
|
+
`AssociationsProvider` (it is now a type error) and any `assertDemandedSchema`
|
|
45
|
+
import. If you want a deliberate schema check in CI, assert against `pg_proc`
|
|
46
|
+
from a server-side script — never by invoking the functions.
|
|
47
|
+
|
|
48
|
+
This release also carries 0.8.10 and 0.8.11, whose artifacts never reached the
|
|
49
|
+
registry (the 0.8.10 workflow stopped on a stale workspace lockfile): the
|
|
50
|
+
regenerated `entity-types.generated.ts` vocabulary at **676 tokens**.
|
|
51
|
+
|
|
3
52
|
## 0.8.11
|
|
4
53
|
|
|
5
54
|
Republishes the 0.8.10 vocabulary artifact under a fresh immutable version.
|
package/README.md
CHANGED
|
@@ -26,7 +26,6 @@ import {
|
|
|
26
26
|
```ts
|
|
27
27
|
import {
|
|
28
28
|
createAssociationsStore, // the ONE runtime object a host constructs
|
|
29
|
-
assertDemandedSchema, // boot probe: every demanded RPC must answer
|
|
30
29
|
} from "@ai-matrx/associations/core";
|
|
31
30
|
|
|
32
31
|
const store = createAssociationsStore({
|
|
@@ -42,10 +41,9 @@ await store.add({ sourceType: "note", sourceId, targetType: "task", targetId });
|
|
|
42
41
|
store.titles.prime("task", taskId, "Renamed");
|
|
43
42
|
await store.favorites.setFavorite("note", noteId, true);
|
|
44
43
|
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
await assertDemandedSchema(supabase, { selfTest: true });
|
|
44
|
+
// There is NO boot check to call (0.9.0). A database that cannot answer a
|
|
45
|
+
// demanded function says so at the first real call: PostgREST returns
|
|
46
|
+
// PGRST202 and the package screams `demanded_schema_violation` with a remedy.
|
|
49
47
|
```
|
|
50
48
|
|
|
51
49
|
`useContainerLinks({ containerType, containerId, orgId })` is the canonical
|
|
@@ -91,7 +89,8 @@ adapt to your database — it DEMANDS ours. A consumer who won't run our schema
|
|
|
91
89
|
not this package's consumer. It ships no DDL (the platform DB owns that; managed
|
|
92
90
|
consumers run on our infrastructure); it ships the demand three ways —
|
|
93
91
|
documented (here), typed (`DemandedRpcSignatures`, generated from the live DB),
|
|
94
|
-
and
|
|
92
|
+
and screamed at the first real call (PGRST202 → `demanded_schema_violation`,
|
|
93
|
+
with a remedy). Every violation
|
|
95
94
|
**screams, never degrades**.
|
|
96
95
|
|
|
97
96
|
1. **The edge.** `platform.associations(source_type, source_id, target_type,
|
|
@@ -335,7 +335,7 @@ type AssociationsRpcErrorCode = "unauthorized" | "forbidden_org" | "forbidden_ro
|
|
|
335
335
|
* on any demanded RPC maps to this code: the database this client is
|
|
336
336
|
* pointed at does not run the schema this package demands (README front
|
|
337
337
|
* door). It always reaches the errorSink — one unambiguous scream, never a
|
|
338
|
-
* mystery toast
|
|
338
|
+
* mystery toast — PGRST202 arrives as `demanded_schema_violation`.
|
|
339
339
|
*/
|
|
340
340
|
| "demanded_schema_violation" | "internal";
|
|
341
341
|
interface AssociationsRpcError {
|
|
@@ -335,7 +335,7 @@ type AssociationsRpcErrorCode = "unauthorized" | "forbidden_org" | "forbidden_ro
|
|
|
335
335
|
* on any demanded RPC maps to this code: the database this client is
|
|
336
336
|
* pointed at does not run the schema this package demands (README front
|
|
337
337
|
* door). It always reaches the errorSink — one unambiguous scream, never a
|
|
338
|
-
* mystery toast
|
|
338
|
+
* mystery toast — PGRST202 arrives as `demanded_schema_violation`.
|
|
339
339
|
*/
|
|
340
340
|
| "demanded_schema_violation" | "internal";
|
|
341
341
|
interface AssociationsRpcError {
|
package/dist/core/index.cjs
CHANGED
|
@@ -23,8 +23,6 @@ __export(core_exports, {
|
|
|
23
23
|
DEFAULT_ORG_COLUMN: () => DEFAULT_ORG_COLUMN,
|
|
24
24
|
DEFAULT_OWNER_COLUMN: () => DEFAULT_OWNER_COLUMN,
|
|
25
25
|
NON_CONTENT_SOURCE_TYPES: () => NON_CONTENT_SOURCE_TYPES,
|
|
26
|
-
SELF_TEST_MISSING_RPC: () => SELF_TEST_MISSING_RPC,
|
|
27
|
-
assertDemandedSchema: () => assertDemandedSchema,
|
|
28
26
|
associationsKey: () => associationsKey,
|
|
29
27
|
buildCategoryHierarchy: () => buildCategoryHierarchy,
|
|
30
28
|
createAssociationGuards: () => createAssociationGuards,
|
|
@@ -3316,169 +3314,6 @@ function createAssociationsStore(config) {
|
|
|
3316
3314
|
};
|
|
3317
3315
|
}
|
|
3318
3316
|
|
|
3319
|
-
// src/demanded-rpcs.generated.ts
|
|
3320
|
-
var DEMANDED_RPC_NAMES = [
|
|
3321
|
-
"assoc_add",
|
|
3322
|
-
"assoc_remove",
|
|
3323
|
-
"assoc_set_targets",
|
|
3324
|
-
"assoc_remove_for_entity",
|
|
3325
|
-
"assoc_for_entity",
|
|
3326
|
-
"assoc_for_targets",
|
|
3327
|
-
"assoc_for_sources",
|
|
3328
|
-
"assoc_members_visible",
|
|
3329
|
-
"conversation_file_add",
|
|
3330
|
-
"conversation_file_remove",
|
|
3331
|
-
"conversation_files",
|
|
3332
|
-
"agent_resource_add",
|
|
3333
|
-
"agent_resource_remove",
|
|
3334
|
-
"cat_list",
|
|
3335
|
-
"cat_create",
|
|
3336
|
-
"cat_update",
|
|
3337
|
-
"cat_reparent",
|
|
3338
|
-
"cat_delete",
|
|
3339
|
-
"ues_set",
|
|
3340
|
-
"ues_list",
|
|
3341
|
-
"ues_get_bulk",
|
|
3342
|
-
"ues_touch",
|
|
3343
|
-
"reference_search_candidates",
|
|
3344
|
-
"cmt_list",
|
|
3345
|
-
"cmt_add",
|
|
3346
|
-
"cmt_edit",
|
|
3347
|
-
"cmt_delete"
|
|
3348
|
-
];
|
|
3349
|
-
|
|
3350
|
-
// src/core/assertDemandedSchema.ts
|
|
3351
|
-
var BAD_UUID = "__not_a_uuid__";
|
|
3352
|
-
var SELF_TEST_MISSING_RPC = "assoc_probe_self_test_missing_fn";
|
|
3353
|
-
var PROBE_ARGS = {
|
|
3354
|
-
// edges — writes
|
|
3355
|
-
assoc_add: {
|
|
3356
|
-
p_source_type: "note",
|
|
3357
|
-
p_source_id: BAD_UUID,
|
|
3358
|
-
p_target_type: "task",
|
|
3359
|
-
p_target_id: BAD_UUID
|
|
3360
|
-
},
|
|
3361
|
-
assoc_remove: {
|
|
3362
|
-
p_source_type: "note",
|
|
3363
|
-
p_source_id: BAD_UUID,
|
|
3364
|
-
p_target_type: "task",
|
|
3365
|
-
p_target_id: BAD_UUID
|
|
3366
|
-
},
|
|
3367
|
-
assoc_set_targets: {
|
|
3368
|
-
p_source_type: "note",
|
|
3369
|
-
p_source_id: BAD_UUID,
|
|
3370
|
-
p_target_type: "task",
|
|
3371
|
-
p_target_ids: [BAD_UUID]
|
|
3372
|
-
},
|
|
3373
|
-
assoc_remove_for_entity: { p_type: "note", p_id: BAD_UUID },
|
|
3374
|
-
// edges — reads
|
|
3375
|
-
assoc_for_entity: { p_type: "note", p_id: BAD_UUID },
|
|
3376
|
-
assoc_for_targets: { p_target_type: "task", p_target_ids: [BAD_UUID] },
|
|
3377
|
-
assoc_for_sources: { p_source_type: "note", p_source_ids: [BAD_UUID] },
|
|
3378
|
-
assoc_members_visible: { p_target_type: "task", p_target_ids: [BAD_UUID] },
|
|
3379
|
-
// conversation files
|
|
3380
|
-
conversation_file_add: {
|
|
3381
|
-
p_conversation_id: BAD_UUID,
|
|
3382
|
-
p_file_id: BAD_UUID
|
|
3383
|
-
},
|
|
3384
|
-
conversation_file_remove: {
|
|
3385
|
-
p_conversation_id: BAD_UUID,
|
|
3386
|
-
p_file_id: BAD_UUID
|
|
3387
|
-
},
|
|
3388
|
-
conversation_files: { p_conversation_id: BAD_UUID },
|
|
3389
|
-
// agent resources
|
|
3390
|
-
agent_resource_add: {
|
|
3391
|
-
p_agent_id: BAD_UUID,
|
|
3392
|
-
p_source_type: "note",
|
|
3393
|
-
p_source_id: BAD_UUID
|
|
3394
|
-
},
|
|
3395
|
-
agent_resource_remove: {
|
|
3396
|
-
p_agent_id: BAD_UUID,
|
|
3397
|
-
p_source_type: "note",
|
|
3398
|
-
p_source_id: BAD_UUID
|
|
3399
|
-
},
|
|
3400
|
-
// categories
|
|
3401
|
-
cat_list: {},
|
|
3402
|
-
cat_create: { p_dimension: "", p_name: "", p_org_id: BAD_UUID },
|
|
3403
|
-
cat_update: { p_category_id: BAD_UUID, p_name: "__probe__" },
|
|
3404
|
-
cat_reparent: { p_category_id: BAD_UUID },
|
|
3405
|
-
cat_delete: { p_category_id: BAD_UUID },
|
|
3406
|
-
// favorites / recents
|
|
3407
|
-
ues_set: { p_entity_type: "__probe__", p_entity_id: BAD_UUID },
|
|
3408
|
-
ues_list: {},
|
|
3409
|
-
ues_get_bulk: { p_entity_type: "__probe__", p_entity_ids: [BAD_UUID] },
|
|
3410
|
-
ues_touch: { p_entity_type: "__probe__", p_entity_id: BAD_UUID },
|
|
3411
|
-
// candidates
|
|
3412
|
-
reference_search_candidates: { p_token: "__probe__", p_limit: 1 },
|
|
3413
|
-
// comments (W6) — every fn takes a uuid arg, so the unparseable sentinel
|
|
3414
|
-
// guarantees 22P02 before any SECURITY DEFINER body runs (no write occurs).
|
|
3415
|
-
cmt_list: { p_entity_type: "__probe__", p_entity_id: BAD_UUID },
|
|
3416
|
-
cmt_add: {
|
|
3417
|
-
p_entity_type: "__probe__",
|
|
3418
|
-
p_entity_id: BAD_UUID,
|
|
3419
|
-
p_body: "__probe__"
|
|
3420
|
-
},
|
|
3421
|
-
cmt_edit: { p_id: BAD_UUID, p_body: "__probe__" },
|
|
3422
|
-
cmt_delete: { p_id: BAD_UUID }
|
|
3423
|
-
};
|
|
3424
|
-
function isMissingFunctionError(error) {
|
|
3425
|
-
if (!error || typeof error !== "object") return false;
|
|
3426
|
-
return error.code === "PGRST202";
|
|
3427
|
-
}
|
|
3428
|
-
async function assertDemandedSchema(dataSource, options = {}) {
|
|
3429
|
-
const { selfTest = false, concurrency = 6, throwOnViolation = true } = options;
|
|
3430
|
-
const names = [...DEMANDED_RPC_NAMES];
|
|
3431
|
-
if (selfTest) names.push(SELF_TEST_MISSING_RPC);
|
|
3432
|
-
const missing = [];
|
|
3433
|
-
const unreachable = [];
|
|
3434
|
-
const answered = [];
|
|
3435
|
-
let cursor = 0;
|
|
3436
|
-
async function worker() {
|
|
3437
|
-
while (cursor < names.length) {
|
|
3438
|
-
const fn = names[cursor];
|
|
3439
|
-
cursor += 1;
|
|
3440
|
-
if (!fn) continue;
|
|
3441
|
-
const args = fn === SELF_TEST_MISSING_RPC ? {} : PROBE_ARGS[fn];
|
|
3442
|
-
try {
|
|
3443
|
-
const { error } = await dataSource.rpc(fn, args);
|
|
3444
|
-
if (error == null) answered.push(fn);
|
|
3445
|
-
else if (isMissingFunctionError(error)) missing.push(fn);
|
|
3446
|
-
else answered.push(fn);
|
|
3447
|
-
} catch (e) {
|
|
3448
|
-
unreachable.push({ fn, error: e });
|
|
3449
|
-
}
|
|
3450
|
-
}
|
|
3451
|
-
}
|
|
3452
|
-
await Promise.all(
|
|
3453
|
-
Array.from({ length: Math.min(concurrency, names.length) }, worker)
|
|
3454
|
-
);
|
|
3455
|
-
if (selfTest) {
|
|
3456
|
-
const selfTestMissing = missing.includes(SELF_TEST_MISSING_RPC);
|
|
3457
|
-
const idx = missing.indexOf(SELF_TEST_MISSING_RPC);
|
|
3458
|
-
if (idx >= 0) missing.splice(idx, 1);
|
|
3459
|
-
const answeredIdx = answered.indexOf(SELF_TEST_MISSING_RPC);
|
|
3460
|
-
if (answeredIdx >= 0) answered.splice(answeredIdx, 1);
|
|
3461
|
-
if (!selfTestMissing) {
|
|
3462
|
-
throw new Error(
|
|
3463
|
-
`assertDemandedSchema self-test FAILED: the fabricated function "${SELF_TEST_MISSING_RPC}" did not come back as missing (PGRST202). This probe cannot currently fail, so its green result proves nothing \u2014 the dataSource is swallowing or faking errors.`
|
|
3464
|
-
);
|
|
3465
|
-
}
|
|
3466
|
-
}
|
|
3467
|
-
if (unreachable.length > 0) {
|
|
3468
|
-
throw new Error(
|
|
3469
|
-
`assertDemandedSchema could not complete: ${unreachable.length} probe call(s) failed to reach the database (${unreachable.map((u) => u.fn).join(", ")}). This is NOT a schema verdict \u2014 fix connectivity and re-run.`
|
|
3470
|
-
);
|
|
3471
|
-
}
|
|
3472
|
-
const ok2 = missing.length === 0;
|
|
3473
|
-
const report = { ok: ok2, missing, unreachable, answered };
|
|
3474
|
-
if (!ok2 && throwOnViolation) {
|
|
3475
|
-
throw new Error(
|
|
3476
|
-
`DEMANDED SCHEMA VIOLATION: the database this dataSource points at cannot answer ${missing.length} demanded @ai-matrx/associations function(s): ${missing.join(", ")}. This package demands the AI Matrx platform schema (README \xA7 The demanded schema); a database without it is not this package's database.`
|
|
3477
|
-
);
|
|
3478
|
-
}
|
|
3479
|
-
return report;
|
|
3480
|
-
}
|
|
3481
|
-
|
|
3482
3317
|
// src/core/edgeClassifier.ts
|
|
3483
3318
|
var NON_CONTENT_SOURCE_TYPES = /* @__PURE__ */ new Set([
|
|
3484
3319
|
"thread",
|