@ai-matrx/kit 0.7.4 → 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 +185 -0
- package/README.md +11 -4
- package/dist/confirm-opener.cjs.map +1 -1
- package/dist/confirm-opener.d.cts +6 -5
- package/dist/confirm-opener.d.ts +6 -5
- package/dist/confirm-opener.js.map +1 -1
- package/dist/format.cjs +210 -0
- package/dist/format.cjs.map +1 -0
- package/dist/format.d.cts +171 -0
- package/dist/format.d.ts +171 -0
- package/dist/format.js +189 -0
- package/dist/format.js.map +1 -0
- package/dist/html-escape.cjs +38 -0
- package/dist/html-escape.cjs.map +1 -0
- package/dist/html-escape.d.cts +40 -0
- package/dist/html-escape.d.ts +40 -0
- package/dist/html-escape.js +17 -0
- package/dist/html-escape.js.map +1 -0
- package/dist/index.cjs +53 -334
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +75 -356
- package/dist/index.js.map +1 -1
- package/dist/uuid.cjs +35 -0
- package/dist/uuid.cjs.map +1 -0
- package/dist/uuid.d.cts +38 -0
- package/dist/uuid.d.ts +38 -0
- package/dist/uuid.js +14 -0
- package/dist/uuid.js.map +1 -0
- package/package.json +39 -16
- package/dist/confirm.cjs +0 -353
- package/dist/confirm.cjs.map +0 -1
- package/dist/confirm.d.cts +0 -139
- package/dist/confirm.d.ts +0 -139
- package/dist/confirm.js +0 -321
- package/dist/confirm.js.map +0 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ai-matrx/kit/html-escape — ONE HTML escaper, with a decided character set.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS FILE EXISTS (2026-09-07 duplication census, row 14). Nine copies of
|
|
5
|
+
* `escapeHtml` were live across the fleet — six in matrx-frontend, one in
|
|
6
|
+
* matrx-extend, one in aidream's dashboard, and one private to
|
|
7
|
+
* `@ai-matrx/print/core` — and **they did not escape the same characters**.
|
|
8
|
+
* Three escaped only `& < >`; two added `"`; four added `'` (two as `'`,
|
|
9
|
+
* two as `'`). A string that is safe through one of them is an attribute
|
|
10
|
+
* break-out through another. That is not a style difference; it is a latent
|
|
11
|
+
* XSS class with nine independent chances to be wrong.
|
|
12
|
+
*
|
|
13
|
+
* The print package was the wrong owner (an HTML escaper must not require the
|
|
14
|
+
* print engine's `jspdf` + `html2canvas` graph), so it lives here, in the
|
|
15
|
+
* package with no sibling dependencies that everything can reach.
|
|
16
|
+
*
|
|
17
|
+
* THE DECIDED SET: `& < > " '` → `& < > " '`.
|
|
18
|
+
*
|
|
19
|
+
* All five, always. Escaping the two quote characters is what makes the result
|
|
20
|
+
* safe to interpolate into an unquoted-or-quoted HTML *attribute*, not just
|
|
21
|
+
* into element text — and every caller that only escaped three was one
|
|
22
|
+
* refactor away from being an attribute caller. `'` uses the numeric `'`
|
|
23
|
+
* rather than the named `'`, which is XML, not HTML 4, and rather than
|
|
24
|
+
* `'`, which is the same character with a pointless leading zero.
|
|
25
|
+
*
|
|
26
|
+
* WHAT THIS IS NOT. This escapes text for an HTML *document* context. It is
|
|
27
|
+
* not a sanitiser for untrusted HTML markup (use a real sanitiser), not a
|
|
28
|
+
* JavaScript-string escaper (a `</script>` inside a JSON blob needs
|
|
29
|
+
* `<`), and not a URL encoder.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Escape `& < > " '` so `value` is safe as HTML element text or as the
|
|
33
|
+
* contents of a quoted HTML attribute.
|
|
34
|
+
*
|
|
35
|
+
* Non-string input returns the empty string rather than `"undefined"` — a
|
|
36
|
+
* literal "undefined" rendered into a page is a screen telling a lie.
|
|
37
|
+
*/
|
|
38
|
+
declare function escapeHtml(value: string | null | undefined): string;
|
|
39
|
+
|
|
40
|
+
export { escapeHtml };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ai-matrx/kit/html-escape — ONE HTML escaper, with a decided character set.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS FILE EXISTS (2026-09-07 duplication census, row 14). Nine copies of
|
|
5
|
+
* `escapeHtml` were live across the fleet — six in matrx-frontend, one in
|
|
6
|
+
* matrx-extend, one in aidream's dashboard, and one private to
|
|
7
|
+
* `@ai-matrx/print/core` — and **they did not escape the same characters**.
|
|
8
|
+
* Three escaped only `& < >`; two added `"`; four added `'` (two as `'`,
|
|
9
|
+
* two as `'`). A string that is safe through one of them is an attribute
|
|
10
|
+
* break-out through another. That is not a style difference; it is a latent
|
|
11
|
+
* XSS class with nine independent chances to be wrong.
|
|
12
|
+
*
|
|
13
|
+
* The print package was the wrong owner (an HTML escaper must not require the
|
|
14
|
+
* print engine's `jspdf` + `html2canvas` graph), so it lives here, in the
|
|
15
|
+
* package with no sibling dependencies that everything can reach.
|
|
16
|
+
*
|
|
17
|
+
* THE DECIDED SET: `& < > " '` → `& < > " '`.
|
|
18
|
+
*
|
|
19
|
+
* All five, always. Escaping the two quote characters is what makes the result
|
|
20
|
+
* safe to interpolate into an unquoted-or-quoted HTML *attribute*, not just
|
|
21
|
+
* into element text — and every caller that only escaped three was one
|
|
22
|
+
* refactor away from being an attribute caller. `'` uses the numeric `'`
|
|
23
|
+
* rather than the named `'`, which is XML, not HTML 4, and rather than
|
|
24
|
+
* `'`, which is the same character with a pointless leading zero.
|
|
25
|
+
*
|
|
26
|
+
* WHAT THIS IS NOT. This escapes text for an HTML *document* context. It is
|
|
27
|
+
* not a sanitiser for untrusted HTML markup (use a real sanitiser), not a
|
|
28
|
+
* JavaScript-string escaper (a `</script>` inside a JSON blob needs
|
|
29
|
+
* `<`), and not a URL encoder.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Escape `& < > " '` so `value` is safe as HTML element text or as the
|
|
33
|
+
* contents of a quoted HTML attribute.
|
|
34
|
+
*
|
|
35
|
+
* Non-string input returns the empty string rather than `"undefined"` — a
|
|
36
|
+
* literal "undefined" rendered into a page is a screen telling a lie.
|
|
37
|
+
*/
|
|
38
|
+
declare function escapeHtml(value: string | null | undefined): string;
|
|
39
|
+
|
|
40
|
+
export { escapeHtml };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/html-escape.ts
|
|
2
|
+
var HTML_ESCAPES = {
|
|
3
|
+
"&": "&",
|
|
4
|
+
"<": "<",
|
|
5
|
+
">": ">",
|
|
6
|
+
'"': """,
|
|
7
|
+
"'": "'"
|
|
8
|
+
};
|
|
9
|
+
var HTML_ESCAPE_RE = /[&<>"']/g;
|
|
10
|
+
function escapeHtml(value) {
|
|
11
|
+
if (typeof value !== "string") return "";
|
|
12
|
+
return value.replace(HTML_ESCAPE_RE, (char) => HTML_ESCAPES[char] ?? char);
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
escapeHtml
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=html-escape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/html-escape.ts"],"sourcesContent":["/**\n * @ai-matrx/kit/html-escape — ONE HTML escaper, with a decided character set.\n *\n * WHY THIS FILE EXISTS (2026-09-07 duplication census, row 14). Nine copies of\n * `escapeHtml` were live across the fleet — six in matrx-frontend, one in\n * matrx-extend, one in aidream's dashboard, and one private to\n * `@ai-matrx/print/core` — and **they did not escape the same characters**.\n * Three escaped only `& < >`; two added `\"`; four added `'` (two as `'`,\n * two as `'`). A string that is safe through one of them is an attribute\n * break-out through another. That is not a style difference; it is a latent\n * XSS class with nine independent chances to be wrong.\n *\n * The print package was the wrong owner (an HTML escaper must not require the\n * print engine's `jspdf` + `html2canvas` graph), so it lives here, in the\n * package with no sibling dependencies that everything can reach.\n *\n * THE DECIDED SET: `& < > \" '` → `& < > " '`.\n *\n * All five, always. Escaping the two quote characters is what makes the result\n * safe to interpolate into an unquoted-or-quoted HTML *attribute*, not just\n * into element text — and every caller that only escaped three was one\n * refactor away from being an attribute caller. `'` uses the numeric `'`\n * rather than the named `'`, which is XML, not HTML 4, and rather than\n * `'`, which is the same character with a pointless leading zero.\n *\n * WHAT THIS IS NOT. This escapes text for an HTML *document* context. It is\n * not a sanitiser for untrusted HTML markup (use a real sanitiser), not a\n * JavaScript-string escaper (a `</script>` inside a JSON blob needs\n * `<`), and not a URL encoder.\n */\n\nconst HTML_ESCAPES: Readonly<Record<string, string>> = {\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n '\"': \""\",\n \"'\": \"'\",\n};\n\nconst HTML_ESCAPE_RE = /[&<>\"']/g;\n\n/**\n * Escape `& < > \" '` so `value` is safe as HTML element text or as the\n * contents of a quoted HTML attribute.\n *\n * Non-string input returns the empty string rather than `\"undefined\"` — a\n * literal \"undefined\" rendered into a page is a screen telling a lie.\n */\nexport function escapeHtml(value: string | null | undefined): string {\n if (typeof value !== \"string\") return \"\";\n return value.replace(HTML_ESCAPE_RE, (char) => HTML_ESCAPES[char] ?? char);\n}\n"],"mappings":";AA+BA,IAAM,eAAiD;AAAA,EACrD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAEA,IAAM,iBAAiB;AAShB,SAAS,WAAW,OAA0C;AACnE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO,MAAM,QAAQ,gBAAgB,CAAC,SAAS,aAAa,IAAI,KAAK,IAAI;AAC3E;","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -31,8 +31,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/index.ts
|
|
32
32
|
var src_exports = {};
|
|
33
33
|
__export(src_exports, {
|
|
34
|
-
ConfirmDialog: () => ConfirmDialog,
|
|
35
|
-
ConfirmDialogHost: () => ConfirmDialogHost,
|
|
36
34
|
DBStoreManager: () => DBStoreManager,
|
|
37
35
|
DEFAULT_JSON_INDENT: () => DEFAULT_JSON_INDENT,
|
|
38
36
|
DEFAULT_JSON_WIDTH: () => DEFAULT_JSON_WIDTH,
|
|
@@ -44,7 +42,6 @@ __export(src_exports, {
|
|
|
44
42
|
captureDrafts: () => captureDrafts,
|
|
45
43
|
commitUrlParams: () => commitUrlParams,
|
|
46
44
|
computeSearchScore: () => computeSearchScore,
|
|
47
|
-
confirm: () => confirm,
|
|
48
45
|
createColorNormalizer: () => createColorNormalizer,
|
|
49
46
|
createFormatter: () => createFormatter,
|
|
50
47
|
createMatrxToast: () => createMatrxToast,
|
|
@@ -925,320 +922,6 @@ function isLocalDraft(value) {
|
|
|
925
922
|
return typeof d.key === "string" && typeof d.namespace === "string" && typeof d.entityId === "string" && typeof d.content === "string" && typeof d.capturedAt === "number";
|
|
926
923
|
}
|
|
927
924
|
|
|
928
|
-
// src/confirm/opener.ts
|
|
929
|
-
var STATE_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.kit.confirm-opener-state");
|
|
930
|
-
function getState() {
|
|
931
|
-
const holder = globalThis;
|
|
932
|
-
let state = holder[STATE_SLOT];
|
|
933
|
-
if (!state) {
|
|
934
|
-
state = { host: null, queue: [] };
|
|
935
|
-
holder[STATE_SLOT] = state;
|
|
936
|
-
}
|
|
937
|
-
return state;
|
|
938
|
-
}
|
|
939
|
-
function _registerHost(controller) {
|
|
940
|
-
const state = getState();
|
|
941
|
-
state.host = controller;
|
|
942
|
-
while (state.queue.length > 0) {
|
|
943
|
-
const next = state.queue.shift();
|
|
944
|
-
controller.show(next.opts, next.resolve);
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
function _unregisterHost(controller) {
|
|
948
|
-
const state = getState();
|
|
949
|
-
if (state.host === controller) state.host = null;
|
|
950
|
-
}
|
|
951
|
-
function confirm(opts) {
|
|
952
|
-
return new Promise((resolve) => {
|
|
953
|
-
const state = getState();
|
|
954
|
-
if (state.host) {
|
|
955
|
-
state.host.show(opts, resolve);
|
|
956
|
-
} else {
|
|
957
|
-
state.queue.push({ opts, resolve });
|
|
958
|
-
}
|
|
959
|
-
});
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
// src/confirm/host.tsx
|
|
963
|
-
var React3 = __toESM(require("react"), 1);
|
|
964
|
-
|
|
965
|
-
// src/confirm/cn.ts
|
|
966
|
-
var import_tailwind_merge = require("tailwind-merge");
|
|
967
|
-
function cn(...values) {
|
|
968
|
-
return (0, import_tailwind_merge.twMerge)(values.filter(Boolean).join(" "));
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
// src/confirm/alert-dialog.tsx
|
|
972
|
-
var React2 = __toESM(require("react"), 1);
|
|
973
|
-
var AlertDialogPrimitive = __toESM(require("@radix-ui/react-alert-dialog"), 1);
|
|
974
|
-
|
|
975
|
-
// src/react-tree.ts
|
|
976
|
-
var React = __toESM(require("react"), 1);
|
|
977
|
-
var REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal");
|
|
978
|
-
function treeContainsComponent(node, Component) {
|
|
979
|
-
if (node == null || typeof node === "boolean") return false;
|
|
980
|
-
if (Array.isArray(node)) {
|
|
981
|
-
return node.some((child) => treeContainsComponent(child, Component));
|
|
982
|
-
}
|
|
983
|
-
if (React.isValidElement(node)) {
|
|
984
|
-
if (node.type === Component) return true;
|
|
985
|
-
const props = node.props;
|
|
986
|
-
return props.children != null ? treeContainsComponent(props.children, Component) : false;
|
|
987
|
-
}
|
|
988
|
-
if (typeof node === "string" || typeof node === "number") return false;
|
|
989
|
-
if (typeof node === "object" && node.$$typeof === REACT_PORTAL_TYPE) {
|
|
990
|
-
return treeContainsComponent(
|
|
991
|
-
node.children,
|
|
992
|
-
Component
|
|
993
|
-
);
|
|
994
|
-
}
|
|
995
|
-
if (typeof node === "object" && Symbol.iterator in node) {
|
|
996
|
-
return Array.from(node).some(
|
|
997
|
-
(child) => treeContainsComponent(child, Component)
|
|
998
|
-
);
|
|
999
|
-
}
|
|
1000
|
-
const runtimeProcess = globalThis.process;
|
|
1001
|
-
if (runtimeProcess?.env?.NODE_ENV !== "production") {
|
|
1002
|
-
const keys = typeof node === "object" ? ` with keys {${Object.keys(node).join(", ")}}` : "";
|
|
1003
|
-
console.error(
|
|
1004
|
-
`[treeContainsComponent] A non-renderable value${keys} is being passed as a React child. React will throw 'Objects are not valid as a React child' at the real render site. Stringify it (e.g. JSON.stringify) before rendering.`,
|
|
1005
|
-
node
|
|
1006
|
-
);
|
|
1007
|
-
}
|
|
1008
|
-
return false;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
// src/confirm/alert-dialog.tsx
|
|
1012
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1013
|
-
var buttonBase = "inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-50 active:scale-[0.98] [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 h-9 px-4 py-2";
|
|
1014
|
-
var buttonDefault = "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90";
|
|
1015
|
-
var buttonOutline = "border border-border bg-card shadow-sm hover:bg-accent hover:text-accent-foreground";
|
|
1016
|
-
var AlertDialog = AlertDialogPrimitive.Root;
|
|
1017
|
-
var AlertDialogPortal = AlertDialogPrimitive.Portal;
|
|
1018
|
-
var AlertDialogOverlay = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1019
|
-
AlertDialogPrimitive.Overlay,
|
|
1020
|
-
{
|
|
1021
|
-
className: cn(
|
|
1022
|
-
"fixed inset-0 z-[10000] bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1023
|
-
className
|
|
1024
|
-
),
|
|
1025
|
-
...props,
|
|
1026
|
-
ref
|
|
1027
|
-
}
|
|
1028
|
-
));
|
|
1029
|
-
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
1030
|
-
var AlertDialogContentPrimitive = React2.forwardRef(({ ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogPrimitive.Content, { ...props, ref, "aria-modal": "true" }));
|
|
1031
|
-
AlertDialogContentPrimitive.displayName = "AlertDialogContentPrimitive";
|
|
1032
|
-
var AlertDialogDescription = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1033
|
-
AlertDialogPrimitive.Description,
|
|
1034
|
-
{
|
|
1035
|
-
ref,
|
|
1036
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
1037
|
-
...props
|
|
1038
|
-
}
|
|
1039
|
-
));
|
|
1040
|
-
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
|
|
1041
|
-
var AlertDialogContent = React2.forwardRef(({ className, children, container, ...props }, ref) => {
|
|
1042
|
-
const hasDescription = treeContainsComponent(children, AlertDialogDescription) || treeContainsComponent(children, AlertDialogPrimitive.Description);
|
|
1043
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AlertDialogPortal, { container: container ?? void 0, children: [
|
|
1044
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogOverlay, {}),
|
|
1045
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1046
|
-
AlertDialogContentPrimitive,
|
|
1047
|
-
{
|
|
1048
|
-
ref,
|
|
1049
|
-
className: cn(
|
|
1050
|
-
"fixed left-[50%] top-[50%] z-[10000] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
|
1051
|
-
className
|
|
1052
|
-
),
|
|
1053
|
-
...props,
|
|
1054
|
-
children: [
|
|
1055
|
-
!hasDescription && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogPrimitive.Description, { className: "sr-only", children: "Please confirm the action described in this dialog." }),
|
|
1056
|
-
children
|
|
1057
|
-
]
|
|
1058
|
-
}
|
|
1059
|
-
)
|
|
1060
|
-
] });
|
|
1061
|
-
});
|
|
1062
|
-
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
|
|
1063
|
-
var AlertDialogHeader = ({
|
|
1064
|
-
className,
|
|
1065
|
-
...props
|
|
1066
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1067
|
-
"div",
|
|
1068
|
-
{
|
|
1069
|
-
className: cn(
|
|
1070
|
-
"flex flex-col space-y-2 text-center sm:text-left",
|
|
1071
|
-
className
|
|
1072
|
-
),
|
|
1073
|
-
...props
|
|
1074
|
-
}
|
|
1075
|
-
);
|
|
1076
|
-
AlertDialogHeader.displayName = "AlertDialogHeader";
|
|
1077
|
-
var AlertDialogFooter = ({
|
|
1078
|
-
className,
|
|
1079
|
-
...props
|
|
1080
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1081
|
-
"div",
|
|
1082
|
-
{
|
|
1083
|
-
className: cn(
|
|
1084
|
-
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
|
1085
|
-
className
|
|
1086
|
-
),
|
|
1087
|
-
...props
|
|
1088
|
-
}
|
|
1089
|
-
);
|
|
1090
|
-
AlertDialogFooter.displayName = "AlertDialogFooter";
|
|
1091
|
-
var AlertDialogTitle = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1092
|
-
AlertDialogPrimitive.Title,
|
|
1093
|
-
{
|
|
1094
|
-
ref,
|
|
1095
|
-
className: cn("text-lg font-semibold", className),
|
|
1096
|
-
...props
|
|
1097
|
-
}
|
|
1098
|
-
));
|
|
1099
|
-
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
1100
|
-
var AlertDialogAction = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1101
|
-
AlertDialogPrimitive.Action,
|
|
1102
|
-
{
|
|
1103
|
-
ref,
|
|
1104
|
-
className: cn(buttonBase, buttonDefault, className),
|
|
1105
|
-
...props
|
|
1106
|
-
}
|
|
1107
|
-
));
|
|
1108
|
-
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
|
1109
|
-
var AlertDialogCancel = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1110
|
-
AlertDialogPrimitive.Cancel,
|
|
1111
|
-
{
|
|
1112
|
-
ref,
|
|
1113
|
-
className: cn(buttonBase, buttonOutline, "mt-2 sm:mt-0", className),
|
|
1114
|
-
...props
|
|
1115
|
-
}
|
|
1116
|
-
));
|
|
1117
|
-
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
|
1118
|
-
|
|
1119
|
-
// src/confirm/confirm-dialog.tsx
|
|
1120
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1121
|
-
function SpinnerIcon({ className }) {
|
|
1122
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1123
|
-
"svg",
|
|
1124
|
-
{
|
|
1125
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1126
|
-
width: 24,
|
|
1127
|
-
height: 24,
|
|
1128
|
-
viewBox: "0 0 24 24",
|
|
1129
|
-
fill: "none",
|
|
1130
|
-
stroke: "currentColor",
|
|
1131
|
-
strokeWidth: 2,
|
|
1132
|
-
strokeLinecap: "round",
|
|
1133
|
-
strokeLinejoin: "round",
|
|
1134
|
-
"aria-hidden": "true",
|
|
1135
|
-
className,
|
|
1136
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
1137
|
-
}
|
|
1138
|
-
);
|
|
1139
|
-
}
|
|
1140
|
-
function ConfirmDialog({
|
|
1141
|
-
open,
|
|
1142
|
-
onOpenChange,
|
|
1143
|
-
title,
|
|
1144
|
-
description,
|
|
1145
|
-
content,
|
|
1146
|
-
contentClassName,
|
|
1147
|
-
confirmLabel = "Confirm",
|
|
1148
|
-
cancelLabel = "Cancel",
|
|
1149
|
-
variant = "default",
|
|
1150
|
-
busy = false,
|
|
1151
|
-
confirmDisabled = false,
|
|
1152
|
-
portalContainer,
|
|
1153
|
-
onConfirm
|
|
1154
|
-
}) {
|
|
1155
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertDialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1156
|
-
AlertDialogContent,
|
|
1157
|
-
{
|
|
1158
|
-
className: contentClassName,
|
|
1159
|
-
container: portalContainer ?? void 0,
|
|
1160
|
-
children: [
|
|
1161
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(AlertDialogHeader, { children: [
|
|
1162
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertDialogTitle, { children: title }),
|
|
1163
|
-
description ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertDialogDescription, { children: description }) : null
|
|
1164
|
-
] }),
|
|
1165
|
-
content ?? null,
|
|
1166
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(AlertDialogFooter, { children: [
|
|
1167
|
-
cancelLabel === null ? null : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertDialogCancel, { className: "max-lg:min-h-11", disabled: busy, children: cancelLabel }),
|
|
1168
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1169
|
-
AlertDialogAction,
|
|
1170
|
-
{
|
|
1171
|
-
disabled: busy || confirmDisabled,
|
|
1172
|
-
onClick: (event) => {
|
|
1173
|
-
event.preventDefault();
|
|
1174
|
-
void onConfirm();
|
|
1175
|
-
},
|
|
1176
|
-
className: cn(
|
|
1177
|
-
"max-lg:min-h-11",
|
|
1178
|
-
variant === "destructive" && "bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
1179
|
-
),
|
|
1180
|
-
children: [
|
|
1181
|
-
busy ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SpinnerIcon, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
1182
|
-
confirmLabel
|
|
1183
|
-
]
|
|
1184
|
-
}
|
|
1185
|
-
)
|
|
1186
|
-
] })
|
|
1187
|
-
]
|
|
1188
|
-
}
|
|
1189
|
-
) });
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
// src/confirm/host.tsx
|
|
1193
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1194
|
-
function ConfirmDialogHost() {
|
|
1195
|
-
const [active, setActive] = React3.useState(null);
|
|
1196
|
-
const [tick, setTick] = React3.useState(0);
|
|
1197
|
-
const queueRef = React3.useRef([]);
|
|
1198
|
-
React3.useEffect(() => {
|
|
1199
|
-
const controller = {
|
|
1200
|
-
show: (opts, resolve) => {
|
|
1201
|
-
queueRef.current.push({ opts, resolve });
|
|
1202
|
-
setTick((n) => n + 1);
|
|
1203
|
-
}
|
|
1204
|
-
};
|
|
1205
|
-
_registerHost(controller);
|
|
1206
|
-
return () => _unregisterHost(controller);
|
|
1207
|
-
}, []);
|
|
1208
|
-
React3.useEffect(() => {
|
|
1209
|
-
if (active === null && queueRef.current.length > 0) {
|
|
1210
|
-
setActive(queueRef.current.shift());
|
|
1211
|
-
}
|
|
1212
|
-
}, [active, tick]);
|
|
1213
|
-
const handleConfirm = React3.useCallback(() => {
|
|
1214
|
-
if (!active) return;
|
|
1215
|
-
active.resolve(true);
|
|
1216
|
-
setActive(null);
|
|
1217
|
-
}, [active]);
|
|
1218
|
-
const handleOpenChange = React3.useCallback(
|
|
1219
|
-
(open) => {
|
|
1220
|
-
if (!open && active) {
|
|
1221
|
-
active.resolve(false);
|
|
1222
|
-
setActive(null);
|
|
1223
|
-
}
|
|
1224
|
-
},
|
|
1225
|
-
[active]
|
|
1226
|
-
);
|
|
1227
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1228
|
-
ConfirmDialog,
|
|
1229
|
-
{
|
|
1230
|
-
open: !!active,
|
|
1231
|
-
onOpenChange: handleOpenChange,
|
|
1232
|
-
title: active?.opts.title ?? "",
|
|
1233
|
-
description: active?.opts.description,
|
|
1234
|
-
confirmLabel: active?.opts.confirmLabel,
|
|
1235
|
-
cancelLabel: active?.opts.cancelLabel,
|
|
1236
|
-
variant: active?.opts.variant,
|
|
1237
|
-
onConfirm: handleConfirm
|
|
1238
|
-
}
|
|
1239
|
-
);
|
|
1240
|
-
}
|
|
1241
|
-
|
|
1242
925
|
// src/toast.ts
|
|
1243
926
|
function messageText(message, data) {
|
|
1244
927
|
const description = data && typeof data.description === "string" ? data.description : "";
|
|
@@ -1289,13 +972,13 @@ function createMatrxToast({
|
|
|
1289
972
|
}
|
|
1290
973
|
|
|
1291
974
|
// src/invalidation.ts
|
|
1292
|
-
var
|
|
975
|
+
var STATE_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.kit.invalidation-registry");
|
|
1293
976
|
function getCallbacks() {
|
|
1294
977
|
const holder = globalThis;
|
|
1295
|
-
let state = holder[
|
|
978
|
+
let state = holder[STATE_SLOT];
|
|
1296
979
|
if (!state) {
|
|
1297
980
|
state = /* @__PURE__ */ new Map();
|
|
1298
|
-
holder[
|
|
981
|
+
holder[STATE_SLOT] = state;
|
|
1299
982
|
}
|
|
1300
983
|
return state;
|
|
1301
984
|
}
|
|
@@ -1749,10 +1432,10 @@ function formatJsonText(text, options) {
|
|
|
1749
1432
|
}
|
|
1750
1433
|
|
|
1751
1434
|
// src/idle-scheduler/scheduler.ts
|
|
1752
|
-
var
|
|
1753
|
-
function
|
|
1435
|
+
var STATE_SLOT2 = /* @__PURE__ */ Symbol.for("ai-matrx.kit.idle-scheduler-state");
|
|
1436
|
+
function getState() {
|
|
1754
1437
|
const holder = globalThis;
|
|
1755
|
-
let state = holder[
|
|
1438
|
+
let state = holder[STATE_SLOT2];
|
|
1756
1439
|
if (!state) {
|
|
1757
1440
|
state = {
|
|
1758
1441
|
queue: /* @__PURE__ */ new Map(),
|
|
@@ -1760,7 +1443,7 @@ function getState2() {
|
|
|
1760
1443
|
cleanupFns: [],
|
|
1761
1444
|
flushListeners: /* @__PURE__ */ new Set()
|
|
1762
1445
|
};
|
|
1763
|
-
holder[
|
|
1446
|
+
holder[STATE_SLOT2] = state;
|
|
1764
1447
|
if (typeof window !== "undefined") {
|
|
1765
1448
|
window.__idleSched = getSchedulerState;
|
|
1766
1449
|
}
|
|
@@ -1768,7 +1451,7 @@ function getState2() {
|
|
|
1768
1451
|
return state;
|
|
1769
1452
|
}
|
|
1770
1453
|
function registerIdleTask(key, priority, callback) {
|
|
1771
|
-
const state =
|
|
1454
|
+
const state = getState();
|
|
1772
1455
|
if (state.flushState === "done") {
|
|
1773
1456
|
scheduleImmediate(callback);
|
|
1774
1457
|
return () => {
|
|
@@ -1783,7 +1466,7 @@ function registerIdleTask(key, priority, callback) {
|
|
|
1783
1466
|
};
|
|
1784
1467
|
}
|
|
1785
1468
|
function onFlushComplete(listener) {
|
|
1786
|
-
const state =
|
|
1469
|
+
const state = getState();
|
|
1787
1470
|
if (state.flushState === "done") {
|
|
1788
1471
|
queueMicrotask(listener);
|
|
1789
1472
|
return () => {
|
|
@@ -1816,7 +1499,7 @@ function whenPageIdle(signal) {
|
|
|
1816
1499
|
});
|
|
1817
1500
|
}
|
|
1818
1501
|
function getSchedulerState() {
|
|
1819
|
-
const state =
|
|
1502
|
+
const state = getState();
|
|
1820
1503
|
return {
|
|
1821
1504
|
flushState: state.flushState,
|
|
1822
1505
|
pendingCount: state.queue.size,
|
|
@@ -1824,7 +1507,7 @@ function getSchedulerState() {
|
|
|
1824
1507
|
};
|
|
1825
1508
|
}
|
|
1826
1509
|
function resetScheduler() {
|
|
1827
|
-
const state =
|
|
1510
|
+
const state = getState();
|
|
1828
1511
|
state.cleanupFns.forEach((fn) => fn());
|
|
1829
1512
|
state.cleanupFns = [];
|
|
1830
1513
|
state.queue.clear();
|
|
@@ -2284,25 +1967,25 @@ var FeatureStore = class extends PublicStoreManager {
|
|
|
2284
1967
|
};
|
|
2285
1968
|
|
|
2286
1969
|
// src/idb-store/singleton.ts
|
|
2287
|
-
var
|
|
2288
|
-
function
|
|
1970
|
+
var STATE_SLOT3 = /* @__PURE__ */ Symbol.for("ai-matrx.kit.idb-store-state");
|
|
1971
|
+
function getState2() {
|
|
2289
1972
|
const holder = globalThis;
|
|
2290
|
-
let state = holder[
|
|
1973
|
+
let state = holder[STATE_SLOT3];
|
|
2291
1974
|
if (!state) {
|
|
2292
1975
|
state = { instances: /* @__PURE__ */ new Map() };
|
|
2293
|
-
holder[
|
|
1976
|
+
holder[STATE_SLOT3] = state;
|
|
2294
1977
|
}
|
|
2295
1978
|
return state;
|
|
2296
1979
|
}
|
|
2297
1980
|
function getIdbStoreSingleton(key, create) {
|
|
2298
|
-
const state =
|
|
1981
|
+
const state = getState2();
|
|
2299
1982
|
if (!state.instances.has(key)) {
|
|
2300
1983
|
state.instances.set(key, create());
|
|
2301
1984
|
}
|
|
2302
1985
|
return state.instances.get(key);
|
|
2303
1986
|
}
|
|
2304
1987
|
function _resetIdbStoreSingletons() {
|
|
2305
|
-
|
|
1988
|
+
getState2().instances.clear();
|
|
2306
1989
|
}
|
|
2307
1990
|
|
|
2308
1991
|
// src/color-util/lab-delta.ts
|
|
@@ -3048,6 +2731,42 @@ function createColorNormalizer({ isValid }) {
|
|
|
3048
2731
|
};
|
|
3049
2732
|
}
|
|
3050
2733
|
|
|
2734
|
+
// src/react-tree.ts
|
|
2735
|
+
var React = __toESM(require("react"), 1);
|
|
2736
|
+
var REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal");
|
|
2737
|
+
function treeContainsComponent(node, Component) {
|
|
2738
|
+
if (node == null || typeof node === "boolean") return false;
|
|
2739
|
+
if (Array.isArray(node)) {
|
|
2740
|
+
return node.some((child) => treeContainsComponent(child, Component));
|
|
2741
|
+
}
|
|
2742
|
+
if (React.isValidElement(node)) {
|
|
2743
|
+
if (node.type === Component) return true;
|
|
2744
|
+
const props = node.props;
|
|
2745
|
+
return props.children != null ? treeContainsComponent(props.children, Component) : false;
|
|
2746
|
+
}
|
|
2747
|
+
if (typeof node === "string" || typeof node === "number") return false;
|
|
2748
|
+
if (typeof node === "object" && node.$$typeof === REACT_PORTAL_TYPE) {
|
|
2749
|
+
return treeContainsComponent(
|
|
2750
|
+
node.children,
|
|
2751
|
+
Component
|
|
2752
|
+
);
|
|
2753
|
+
}
|
|
2754
|
+
if (typeof node === "object" && Symbol.iterator in node) {
|
|
2755
|
+
return Array.from(node).some(
|
|
2756
|
+
(child) => treeContainsComponent(child, Component)
|
|
2757
|
+
);
|
|
2758
|
+
}
|
|
2759
|
+
const runtimeProcess = globalThis.process;
|
|
2760
|
+
if (runtimeProcess?.env?.NODE_ENV !== "production") {
|
|
2761
|
+
const keys = typeof node === "object" ? ` with keys {${Object.keys(node).join(", ")}}` : "";
|
|
2762
|
+
console.error(
|
|
2763
|
+
`[treeContainsComponent] A non-renderable value${keys} is being passed as a React child. React will throw 'Objects are not valid as a React child' at the real render site. Stringify it (e.g. JSON.stringify) before rendering.`,
|
|
2764
|
+
node
|
|
2765
|
+
);
|
|
2766
|
+
}
|
|
2767
|
+
return false;
|
|
2768
|
+
}
|
|
2769
|
+
|
|
3051
2770
|
// src/qr.ts
|
|
3052
2771
|
var MAX_EDGE = 1600;
|
|
3053
2772
|
function nativeDetector() {
|