@ai-matrx/records 0.3.3 → 0.4.1

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 CHANGED
@@ -1,33 +1,42 @@
1
1
  # Changelog — @ai-matrx/records
2
2
 
3
- ## 0.3.3
3
+ ## 0.4.1
4
4
 
5
- Lets a legitimate competing live-store verification finish instead of treating
6
- five seconds of advisory-lock contention as a package failure, while retaining
7
- a hard statement timeout for genuinely abandoned transactions.
5
+ Carries the live Supabase adapter proof through the shared npm publishing lane
6
+ by supplying its existing main-database HTTP URL and publishable-key secrets to
7
+ the verification step.
8
8
 
9
9
  ### Consumer action
10
10
 
11
- None. This changes only the release-time real-store verification lane.
12
-
13
- ## 0.3.2
14
-
15
- Refreshes the generated store contract to the live 238-door, 32-knob registry
16
- and serializes the shared record-store release lane with `records-ui`. This
17
- prevents either package's live verification from observing the other suite's
18
- temporary store state.
19
-
20
- ### Consumer action
21
-
22
- None. The new door and knob entries are additive generated contract data.
23
-
24
- ## 0.3.1
25
-
26
- The real-store verification lane now takes one transaction-scoped advisory lock before it
27
- opens the record-store feature knob. Parallel package and UI verification waits its turn
28
- instead of converting unrelated knob contention into a false store refusal.
29
-
30
- **Consumer action:** none.
11
+ None beyond taking `latest`; the 0.4.0 API is unchanged.
12
+
13
+ ## 0.4.0
14
+
15
+ **The browser can reach the store again `supabaseDataSource`.** Every screen
16
+ of the record store was dead from a browser, for everybody, and the cause was a
17
+ single silent drop. `RecordsDataSource.rpc(fn, args, { schema })` says the
18
+ schema out loud, because every door is `custom.<name>` and every trust door is
19
+ `iam.<name>`. supabase-js's own `rpc()` has NO schema option — its third
20
+ argument is `{ head, get, count }` — so a host that bound its client as a bare
21
+ structural cast handed the option to a function that dropped it, every door call
22
+ went to PostgREST's default profile, and the store answered, correctly and
23
+ uselessly, `PGRST202 — Could not find the function public.table_kernel_id in the
24
+ schema cache`. Independent verdict, 2026-09-19.
25
+
26
+ The fix is ONE adapter in the headless core, exported from `/core`, that every
27
+ host inherits never three hosts (web, desktop, extension) each remembering the
28
+ same thing. It routes through `client.schema(name).rpc(...)`, which is the one
29
+ way supabase-js offers, and it refuses two things by name rather than sending
30
+ them: a call with no schema (which would reach `public`), and a client with no
31
+ `.schema()` method (which would throw inside a render).
32
+
33
+ **The test that would have caught it**, `src/__tests__/supabase-adapter.test.ts`:
34
+ a real supabase-js client against the MAIN database, signed in as `test@test.com`,
35
+ calling a real door. A raw `fetch` to `/rest/v1/rpc/...` would NOT have caught
36
+ this — the bug is in supabase-js's option handling, so only a real client
37
+ exercises it. The RED half reconstructs the bare cast that shipped and asserts
38
+ the store's own PGRST202 naming `public`; the GREEN half is the same call
39
+ through the adapter answering the kernel id.
31
40
 
32
41
  ## 0.3.0
33
42
 
@@ -90,6 +90,7 @@ __export(core_exports, {
90
90
  predictValueRefusals: () => predictValueRefusals,
91
91
  predictWriteRefusals: () => predictWriteRefusals,
92
92
  staleWriteDetail: () => staleWriteDetail,
93
+ supabaseDataSource: () => supabaseDataSource,
93
94
  toAoa: () => toAoa
94
95
  });
95
96
  module.exports = __toCommonJS(core_exports);
@@ -2575,6 +2576,42 @@ function asWriteConflict(error, recordId) {
2575
2576
  };
2576
2577
  }
2577
2578
 
2579
+ // src/core/supabase.ts
2580
+ function refuse(code, message, hint) {
2581
+ return { data: null, error: { code, message, hint, details: "" } };
2582
+ }
2583
+ function supabaseDataSource(client) {
2584
+ const supabase = client;
2585
+ const hasSchema = typeof supabase.schema === "function";
2586
+ return {
2587
+ rpc(fn, args, options) {
2588
+ if (!hasSchema) {
2589
+ return Promise.resolve(
2590
+ refuse(
2591
+ "data_source_unbound",
2592
+ `The records client was given something that is not a supabase client: it has no schema() method, so the door ${fn} cannot be called in the schema it lives in.`,
2593
+ "Pass a supabase-js v2 client (createClient(...)) to supabaseDataSource()."
2594
+ )
2595
+ );
2596
+ }
2597
+ const name = options?.schema;
2598
+ if (!name) {
2599
+ return Promise.resolve(
2600
+ refuse(
2601
+ "schema_unsaid",
2602
+ `The door ${fn} was called without saying which schema it lives in. Every door of this store is custom.${fn} and every trust door is iam.${fn}; an unqualified call reaches PostgREST's default profile (public) and is refused there.`,
2603
+ "This is a bug in the caller, not in your data: /core says the schema on every call."
2604
+ )
2605
+ );
2606
+ }
2607
+ return supabase.schema(name).rpc(fn, args);
2608
+ },
2609
+ schema(name) {
2610
+ return supabase.schema(name);
2611
+ }
2612
+ };
2613
+ }
2614
+
2578
2615
  // src/core/validation.ts
2579
2616
  var DEFAULT_VALUE_MAX_BYTES = 1e5;
2580
2617
  var DEFAULT_DOCUMENT_MAX_BYTES = 1048576;