@ai-matrx/associations 0.11.4 → 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/CHANGELOG.md +60 -0
- package/dist/{CommentThread-DDeqHgTk.d.cts → CommentThread-DP4sEzb2.d.cts} +25 -8
- package/dist/{CommentThread-DDeqHgTk.d.ts → CommentThread-DP4sEzb2.d.ts} +25 -8
- package/dist/core/index.cjs +9 -4
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +20 -7
- package/dist/core/index.d.ts +20 -7
- package/dist/core/index.js +9 -4
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +740 -545
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +48 -6
- package/dist/react/index.d.ts +48 -6
- package/dist/react/index.js +723 -528
- 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,65 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/associations
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
A search that could not look no longer says "no results".
|
|
6
|
+
|
|
7
|
+
* **Breaking:** `searchCandidatesAcrossTokens` returns `{ results, failures }` instead of a bare
|
|
8
|
+
array. `failures: TokenSearchFailure[]` (`{ token, error }`, registry order) lists every token
|
|
9
|
+
whose read failed — those tokens used to be screamed and silently dropped, so a search where
|
|
10
|
+
some or all tokens failed looked like "nothing matched". Result order and the per-token cap are
|
|
11
|
+
unchanged. New types `SearchAcrossTokensResult`, `TokenSearchFailure` (from `/core`).
|
|
12
|
+
* `useUniversalEntitySearch` also returns `failures: UniversalSearchFailure[]` (`token: null` =
|
|
13
|
+
the recents read failed), `error` (non-null only when nothing could be read — every token
|
|
14
|
+
failed, or the recents read failed and the fallback browse failed too) and
|
|
15
|
+
`status: "loading" | "error" | "ready"`. A failed recents read still falls back to browsing,
|
|
16
|
+
but is recorded in `failures` — never silently turned into a browse.
|
|
17
|
+
* New `SearchFailureNotice` + `describeSearchFailures` (`/react`): the one way a face shows the
|
|
18
|
+
hook's failures — the ErrorBox failure block when `error` is set, and a one-line
|
|
19
|
+
"Couldn't search Notes, Tasks" note above partial results. `UniversalAssociationPicker` and the
|
|
20
|
+
`AssociationPicker` recents strip render it.
|
|
21
|
+
* **Breaking:** `ownerId` removed from `ListCandidatesArgs`, `SearchAcrossTokensArgs`,
|
|
22
|
+
`UseUniversalEntitySearchArgs` and `UniversalAssociationPickerProps`. It was never applied —
|
|
23
|
+
`public.reference_search_candidates(p_token, p_search, p_limit, p_ids)` has no owner
|
|
24
|
+
parameter; visibility is the RPC's alone. An ignored filter is a lie.
|
|
25
|
+
|
|
26
|
+
**Consumer action:** read `.results` (and handle `.failures`) from
|
|
27
|
+
`searchCandidatesAcrossTokens`; stop passing `ownerId` to the candidate reads, the hook and
|
|
28
|
+
`UniversalAssociationPicker`; render `SearchFailureNotice` (or your own use of `error` /
|
|
29
|
+
`failures`) wherever you render `useUniversalEntitySearch` results.
|
|
30
|
+
|
|
31
|
+
## 0.12.1
|
|
32
|
+
|
|
33
|
+
Re-cut of 0.12.0 — same package source. The 0.12.0 tag was cut from a commit whose workspace
|
|
34
|
+
lockfile did not match `shared/messaging/package.json` (ERR_PNPM_OUTDATED_LOCKFILE), so its
|
|
35
|
+
publish could never install; an immutable tag cannot move, so the bytes ship as 0.12.1.
|
|
36
|
+
No consumer action beyond 0.12.0's.
|
|
37
|
+
|
|
38
|
+
## 0.12.0
|
|
39
|
+
|
|
40
|
+
* `UniversalAssociationPicker`: an empty search box with no recents (favorites / last-viewed) now
|
|
41
|
+
**browses candidates across the offered tokens** instead of saying "No recent items" — it was a
|
|
42
|
+
screen that lied for an account with hundreds of records it had never opened. Results carry a
|
|
43
|
+
"Recent" or "Browse" label.
|
|
44
|
+
* `UniversalAssociationPicker` takes `emptyQueryMode?: "recents" | "candidates"` (default
|
|
45
|
+
`"recents"`, which falls back as above).
|
|
46
|
+
* `useUniversalEntitySearch` returns `source: "search" | "recents" | "candidates"` (new
|
|
47
|
+
`UniversalSearchSource` type); `isRecents` is unchanged in meaning.
|
|
48
|
+
* A chip whose token has a `pickerOverrides` component (Files → the host's window) no longer
|
|
49
|
+
leaves the picker body blank: it says the window is open (or closed), offers "Bring window to
|
|
50
|
+
front" / "Reopen window", and "Back to search". Closing the override window keeps the chip
|
|
51
|
+
selected instead of silently dropping back to search.
|
|
52
|
+
|
|
53
|
+
**Consumer action:** none required. Hosts whose override window renders attached state should
|
|
54
|
+
read `AssociationPickerProps.attachedIds` (it has always been passed; matrx-frontend's file
|
|
55
|
+
override did not read it until this release's adoption).
|
|
56
|
+
|
|
57
|
+
## 0.11.5
|
|
58
|
+
|
|
59
|
+
Automatic changed-only republish, cut by the release train while the 0.12.0 source below was
|
|
60
|
+
already on `main` (a checkout sweep committed it before its own version bump) — so 0.11.5 DOES
|
|
61
|
+
carry the 0.12.0 picker changes despite its auto text. Adopt 0.12.0.
|
|
62
|
+
|
|
3
63
|
## 0.11.4
|
|
4
64
|
|
|
5
65
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
@@ -1008,8 +1008,6 @@ interface CandidateRecord {
|
|
|
1008
1008
|
}
|
|
1009
1009
|
interface ListCandidatesArgs {
|
|
1010
1010
|
token: EntityTypeToken;
|
|
1011
|
-
/** Scope to this owner's rows when the entity declares an owner column. */
|
|
1012
|
-
ownerId?: string | null;
|
|
1013
1011
|
/** Case-insensitive title filter. */
|
|
1014
1012
|
search?: string;
|
|
1015
1013
|
limit?: number;
|
|
@@ -1028,12 +1026,25 @@ interface SearchAcrossTokensArgs {
|
|
|
1028
1026
|
/** Tokens to search. Defaults to every curated token in the registry. */
|
|
1029
1027
|
tokens?: EntityTypeToken[];
|
|
1030
1028
|
search: string;
|
|
1031
|
-
ownerId?: string | null;
|
|
1032
1029
|
/** Cap per token — a universal search shows a few of everything. */
|
|
1033
1030
|
perTokenLimit?: number;
|
|
1034
1031
|
/** Max in-flight token queries. */
|
|
1035
1032
|
concurrency?: number;
|
|
1036
1033
|
}
|
|
1034
|
+
/** One token whose candidate read failed during a cross-token search. */
|
|
1035
|
+
interface TokenSearchFailure {
|
|
1036
|
+
token: EntityTypeToken;
|
|
1037
|
+
error: string;
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* A cross-token search's honest answer: what could be read, AND what could
|
|
1041
|
+
* not. An empty `results` with non-empty `failures` is "we couldn't look",
|
|
1042
|
+
* never "there is nothing".
|
|
1043
|
+
*/
|
|
1044
|
+
interface SearchAcrossTokensResult {
|
|
1045
|
+
results: UniversalCandidate[];
|
|
1046
|
+
failures: TokenSearchFailure[];
|
|
1047
|
+
}
|
|
1037
1048
|
interface ReferenceSearchCandidatesFn {
|
|
1038
1049
|
(args: {
|
|
1039
1050
|
p_token: string;
|
|
@@ -1063,10 +1074,12 @@ interface CandidatesServiceApi {
|
|
|
1063
1074
|
/**
|
|
1064
1075
|
* ONE search over EVERY listable entity type — the "attach anything from
|
|
1065
1076
|
* anywhere" primitive. Registry-driven client fan-out, capped and
|
|
1066
|
-
* concurrency-limited.
|
|
1067
|
-
*
|
|
1077
|
+
* concurrency-limited. One broken table never blanks the search: a failed
|
|
1078
|
+
* token is screamed (errorSink) AND reported in `failures` (registry
|
|
1079
|
+
* order), so a face can say what it could not search instead of showing
|
|
1080
|
+
* "no results".
|
|
1068
1081
|
*/
|
|
1069
|
-
searchCandidatesAcrossTokens(args: SearchAcrossTokensArgs): Promise<
|
|
1082
|
+
searchCandidatesAcrossTokens(args: SearchAcrossTokensArgs): Promise<SearchAcrossTokensResult>;
|
|
1070
1083
|
}
|
|
1071
1084
|
|
|
1072
1085
|
interface TitlesServiceApi {
|
|
@@ -1630,10 +1643,14 @@ interface UniversalAssociationPickerProps {
|
|
|
1630
1643
|
ok: boolean;
|
|
1631
1644
|
error?: string;
|
|
1632
1645
|
}>;
|
|
1633
|
-
/** Owner filter for candidate reads (defaults to RLS-only). */
|
|
1634
|
-
ownerId?: string | null;
|
|
1635
1646
|
/** Org stamped onto rows created via the per-token "+ New" footer. */
|
|
1636
1647
|
orgId?: string | null;
|
|
1648
|
+
/**
|
|
1649
|
+
* What an empty search box shows. `"recents"` (default) shows favorites and
|
|
1650
|
+
* last-viewed records and falls back to browsing candidates when there are
|
|
1651
|
+
* none; `"candidates"` always browses the available records.
|
|
1652
|
+
*/
|
|
1653
|
+
emptyQueryMode?: "recents" | "candidates";
|
|
1637
1654
|
className?: string;
|
|
1638
1655
|
}
|
|
1639
1656
|
declare function attachedKey(token: string, id: string): string;
|
|
@@ -1008,8 +1008,6 @@ interface CandidateRecord {
|
|
|
1008
1008
|
}
|
|
1009
1009
|
interface ListCandidatesArgs {
|
|
1010
1010
|
token: EntityTypeToken;
|
|
1011
|
-
/** Scope to this owner's rows when the entity declares an owner column. */
|
|
1012
|
-
ownerId?: string | null;
|
|
1013
1011
|
/** Case-insensitive title filter. */
|
|
1014
1012
|
search?: string;
|
|
1015
1013
|
limit?: number;
|
|
@@ -1028,12 +1026,25 @@ interface SearchAcrossTokensArgs {
|
|
|
1028
1026
|
/** Tokens to search. Defaults to every curated token in the registry. */
|
|
1029
1027
|
tokens?: EntityTypeToken[];
|
|
1030
1028
|
search: string;
|
|
1031
|
-
ownerId?: string | null;
|
|
1032
1029
|
/** Cap per token — a universal search shows a few of everything. */
|
|
1033
1030
|
perTokenLimit?: number;
|
|
1034
1031
|
/** Max in-flight token queries. */
|
|
1035
1032
|
concurrency?: number;
|
|
1036
1033
|
}
|
|
1034
|
+
/** One token whose candidate read failed during a cross-token search. */
|
|
1035
|
+
interface TokenSearchFailure {
|
|
1036
|
+
token: EntityTypeToken;
|
|
1037
|
+
error: string;
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* A cross-token search's honest answer: what could be read, AND what could
|
|
1041
|
+
* not. An empty `results` with non-empty `failures` is "we couldn't look",
|
|
1042
|
+
* never "there is nothing".
|
|
1043
|
+
*/
|
|
1044
|
+
interface SearchAcrossTokensResult {
|
|
1045
|
+
results: UniversalCandidate[];
|
|
1046
|
+
failures: TokenSearchFailure[];
|
|
1047
|
+
}
|
|
1037
1048
|
interface ReferenceSearchCandidatesFn {
|
|
1038
1049
|
(args: {
|
|
1039
1050
|
p_token: string;
|
|
@@ -1063,10 +1074,12 @@ interface CandidatesServiceApi {
|
|
|
1063
1074
|
/**
|
|
1064
1075
|
* ONE search over EVERY listable entity type — the "attach anything from
|
|
1065
1076
|
* anywhere" primitive. Registry-driven client fan-out, capped and
|
|
1066
|
-
* concurrency-limited.
|
|
1067
|
-
*
|
|
1077
|
+
* concurrency-limited. One broken table never blanks the search: a failed
|
|
1078
|
+
* token is screamed (errorSink) AND reported in `failures` (registry
|
|
1079
|
+
* order), so a face can say what it could not search instead of showing
|
|
1080
|
+
* "no results".
|
|
1068
1081
|
*/
|
|
1069
|
-
searchCandidatesAcrossTokens(args: SearchAcrossTokensArgs): Promise<
|
|
1082
|
+
searchCandidatesAcrossTokens(args: SearchAcrossTokensArgs): Promise<SearchAcrossTokensResult>;
|
|
1070
1083
|
}
|
|
1071
1084
|
|
|
1072
1085
|
interface TitlesServiceApi {
|
|
@@ -1630,10 +1643,14 @@ interface UniversalAssociationPickerProps {
|
|
|
1630
1643
|
ok: boolean;
|
|
1631
1644
|
error?: string;
|
|
1632
1645
|
}>;
|
|
1633
|
-
/** Owner filter for candidate reads (defaults to RLS-only). */
|
|
1634
|
-
ownerId?: string | null;
|
|
1635
1646
|
/** Org stamped onto rows created via the per-token "+ New" footer. */
|
|
1636
1647
|
orgId?: string | null;
|
|
1648
|
+
/**
|
|
1649
|
+
* What an empty search box shows. `"recents"` (default) shows favorites and
|
|
1650
|
+
* last-viewed records and falls back to browsing candidates when there are
|
|
1651
|
+
* none; `"candidates"` always browses the available records.
|
|
1652
|
+
*/
|
|
1653
|
+
emptyQueryMode?: "recents" | "candidates";
|
|
1637
1654
|
className?: string;
|
|
1638
1655
|
}
|
|
1639
1656
|
declare function attachedKey(token: string, id: string): string;
|
package/dist/core/index.cjs
CHANGED
|
@@ -3112,10 +3112,11 @@ function createCandidatesService(deps) {
|
|
|
3112
3112
|
};
|
|
3113
3113
|
}
|
|
3114
3114
|
async function searchCandidatesAcrossTokens(args) {
|
|
3115
|
-
const { tokens, search,
|
|
3115
|
+
const { tokens, search, perTokenLimit = 5, concurrency = 6 } = args;
|
|
3116
3116
|
const list = tokens ?? registry.listableTokens();
|
|
3117
|
-
if (list.length === 0) return [];
|
|
3117
|
+
if (list.length === 0) return { results: [], failures: [] };
|
|
3118
3118
|
const out = [];
|
|
3119
|
+
const failures = [];
|
|
3119
3120
|
let cursor = 0;
|
|
3120
3121
|
async function worker() {
|
|
3121
3122
|
while (cursor < list.length) {
|
|
@@ -3124,12 +3125,13 @@ function createCandidatesService(deps) {
|
|
|
3124
3125
|
if (!token) continue;
|
|
3125
3126
|
const res = await listAssociationCandidates({
|
|
3126
3127
|
token,
|
|
3127
|
-
ownerId: ownerId ?? null,
|
|
3128
3128
|
search,
|
|
3129
3129
|
limit: perTokenLimit
|
|
3130
3130
|
});
|
|
3131
3131
|
if (res.ok) {
|
|
3132
3132
|
for (const c of res.data) out.push({ ...c, token });
|
|
3133
|
+
} else {
|
|
3134
|
+
failures.push({ token, error: res.error });
|
|
3133
3135
|
}
|
|
3134
3136
|
}
|
|
3135
3137
|
}
|
|
@@ -3143,7 +3145,10 @@ function createCandidatesService(deps) {
|
|
|
3143
3145
|
if (ta !== tb) return ta - tb;
|
|
3144
3146
|
return a.title.localeCompare(b.title);
|
|
3145
3147
|
});
|
|
3146
|
-
|
|
3148
|
+
failures.sort(
|
|
3149
|
+
(a, b) => (tokenOrder.get(a.token) ?? 0) - (tokenOrder.get(b.token) ?? 0)
|
|
3150
|
+
);
|
|
3151
|
+
return { results: out, failures };
|
|
3147
3152
|
}
|
|
3148
3153
|
return {
|
|
3149
3154
|
callReferenceSearchCandidates,
|