@immediately-run/sdk 0.23.0 → 0.24.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/components/WikiLink.cjs +48 -3
- package/dist/components/WikiLink.cjs.map +1 -1
- package/dist/components/WikiLink.d.cts +24 -11
- package/dist/components/WikiLink.d.ts +24 -11
- package/dist/components/WikiLink.js +48 -3
- package/dist/components/WikiLink.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -22,20 +22,65 @@ __export(WikiLink_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(WikiLink_exports);
|
|
24
24
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
25
|
+
var import_react = require("react");
|
|
25
26
|
var import_Link = require("./Link");
|
|
27
|
+
var import_Include = require("./Include");
|
|
28
|
+
var import_TinkerableContext = require("../TinkerableContext");
|
|
26
29
|
const labelFromTarget = (target) => {
|
|
27
30
|
const base = target.split(/[\\/]/).pop() ?? target;
|
|
28
31
|
return base.replace(/\.mdx?$/i, "") || target;
|
|
29
32
|
};
|
|
33
|
+
const normalize = (path) => {
|
|
34
|
+
const out = [];
|
|
35
|
+
for (const seg of path.split("/")) {
|
|
36
|
+
if (seg === "" || seg === ".") continue;
|
|
37
|
+
if (seg === "..") out.pop();
|
|
38
|
+
else out.push(seg);
|
|
39
|
+
}
|
|
40
|
+
return "/" + out.join("/");
|
|
41
|
+
};
|
|
42
|
+
const resolveWikiTarget = (target, currentFile) => {
|
|
43
|
+
if (target.startsWith("/")) return normalize(target);
|
|
44
|
+
if (!currentFile) return void 0;
|
|
45
|
+
const dir = currentFile.slice(0, currentFile.lastIndexOf("/"));
|
|
46
|
+
return normalize(`${dir}/${target}`);
|
|
47
|
+
};
|
|
30
48
|
const WikiLink = ({
|
|
31
49
|
target,
|
|
32
50
|
label,
|
|
33
51
|
children,
|
|
34
52
|
...rest
|
|
35
53
|
}) => {
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
54
|
+
const { filesMetadata } = (0, import_react.use)(import_TinkerableContext.TinkerableContext);
|
|
55
|
+
const renderContext = (0, import_react.use)(import_Include.RenderExportedComponentContext);
|
|
56
|
+
const currentFile = renderContext?.evaluationContext?.evaluation?.module?.filepath;
|
|
57
|
+
const rawTarget = target ?? "";
|
|
58
|
+
const text = children ?? label ?? (rawTarget ? labelFromTarget(rawTarget) : "");
|
|
59
|
+
if (!rawTarget) {
|
|
60
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ir-wikilink", ...rest, children: text });
|
|
61
|
+
}
|
|
62
|
+
const resolved = resolveWikiTarget(rawTarget, currentFile);
|
|
63
|
+
const files = filesMetadata ?? {};
|
|
64
|
+
const loaded = Object.keys(files).length > 0;
|
|
65
|
+
if (resolved !== void 0) {
|
|
66
|
+
if (currentFile && resolved === currentFile) {
|
|
67
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ir-wikilink ir-wikilink-self", "data-state": "self", ...rest, children: text });
|
|
68
|
+
}
|
|
69
|
+
const exists = !loaded || resolved in files;
|
|
70
|
+
if (!exists) {
|
|
71
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
72
|
+
"span",
|
|
73
|
+
{
|
|
74
|
+
className: "ir-wikilink ir-wikilink-broken",
|
|
75
|
+
"data-state": "broken",
|
|
76
|
+
title: `No file at ${resolved}`,
|
|
77
|
+
...rest,
|
|
78
|
+
children: text
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Link.Link, { href: rawTarget, className: "ir-wikilink", "data-state": "resolved", ...rest, children: text });
|
|
39
84
|
};
|
|
40
85
|
// Annotate the CommonJS export names for ESM import in node:
|
|
41
86
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/WikiLink.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport { Link } from './Link';\n\n/** Derive a human label from a target path: basename without the extension. */\nconst labelFromTarget = (target: string): string => {\n const base = target.split(/[\\\\/]/).pop() ?? target;\n return base.replace(/\\.mdx?$/i, '') || target;\n};\n\n/**\n * Default MDX `WikiLink` component — the render target for the `[[target]]` /\n * `[[label|target]]` wiki-link syntax
|
|
1
|
+
{"version":3,"sources":["../../src/components/WikiLink.tsx"],"sourcesContent":["import { ReactNode, use } from 'react';\nimport { Link } from './Link';\nimport { RenderExportedComponentContext } from './Include';\nimport { TinkerableContext } from '../TinkerableContext';\n\n/** Derive a human label from a target path: basename without the extension. */\nconst labelFromTarget = (target: string): string => {\n const base = target.split(/[\\\\/]/).pop() ?? target;\n return base.replace(/\\.mdx?$/i, '') || target;\n};\n\n/** Collapse `.`/`..`/empty segments into a clean absolute path. */\nconst normalize = (path: string): string => {\n const out: string[] = [];\n for (const seg of path.split('/')) {\n if (seg === '' || seg === '.') continue;\n if (seg === '..') out.pop();\n else out.push(seg);\n }\n return '/' + out.join('/');\n};\n\n/**\n * Resolve a wiki-link target to an absolute sandbox path, or `undefined` when it\n * cannot be resolved (a relative target with no known current file). An\n * **absolute** target (`/…`) is taken verbatim; a **relative** target resolves\n * against the current file's directory. Pure path arithmetic (MARKDOWN_SYNTAX_SPEC\n * §13.2) — it never touches the filesystem or any other file.\n */\nconst resolveWikiTarget = (target: string, currentFile?: string): string | undefined => {\n if (target.startsWith('/')) return normalize(target);\n if (!currentFile) return undefined;\n const dir = currentFile.slice(0, currentFile.lastIndexOf('/'));\n return normalize(`${dir}/${target}`);\n};\n\n/**\n * Default MDX `WikiLink` component — the render target for the `[[target]]` /\n * `[[label|target]]` wiki-link syntax. The transpiler remark plugin (R3-153)\n * compiles that syntax to `<WikiLink target=\"…\" label=\"…\">`, carrying the raw\n * target/label verbatim; **resolution lives here** (MARKDOWN_SYNTAX_SPEC §13.2).\n *\n * Registered in {@link DEFAULT_MDX_COMPONENTS} so wiki-links render even in a\n * plain-markdown repo (§11.2 phantom defaults). Targets are **paths only** —\n * relative (resolved against the current file's directory) or absolute — with\n * **no implicit search path** (§13.3, a deliberate departure from Obsidian).\n *\n * The **current file** — the one the link is *authored in* — is read from the\n * ambient `<Include>` render context. Every MDX file renders through `<Include>`\n * (`FileRouter` renders even the top-level file that way), and Include publishes\n * the rendered module's `EvaluationContext` to its subtree via\n * {@link RenderExportedComponentContext}; the nearest one's\n * `evaluation.module.filepath` is this file's own `/app/…` path. Because that\n * context nests with each `<Include>`, a relative target inside an included\n * fragment resolves against the **fragment**, not the top-level page in the URL.\n *\n * The resolved path is checked for **existence** against the live metadata store\n * (keyed by absolute `/app/…` paths) for the three states (§13.3):\n * - **self** — the resolved path is the current file: inert text, no link.\n * - **broken** — no file at the resolved path (and the store has loaded): rendered\n * as marked text, **not** a throw.\n * - **resolved** — routed through {@link Link} (in-app navigation for a same-app\n * href, a plain `<a>` otherwise).\n *\n * The check is **optimistic until the metadata store loads** (an empty store never\n * flashes \"broken\"), and a relative target with no ambient render context (MDX\n * rendered outside `<Include>`) routes optimistically. Such an app overrides this\n * component (§11) for precise resolution.\n */\nexport const WikiLink = ({\n target,\n label,\n children,\n ...rest\n}: {\n target?: string;\n label?: ReactNode;\n children?: ReactNode;\n} & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>): ReactNode => {\n const { filesMetadata } = use(TinkerableContext);\n const renderContext = use(RenderExportedComponentContext);\n const currentFile = renderContext?.evaluationContext?.evaluation?.module?.filepath;\n\n const rawTarget = target ?? '';\n const text = children ?? label ?? (rawTarget ? labelFromTarget(rawTarget) : '');\n\n // Defensive: the kernel never emits an empty target, but a hand-written\n // `<WikiLink>` might. Render inert text rather than a link to nowhere.\n if (!rawTarget) {\n return (\n <span className=\"ir-wikilink\" {...rest}>\n {text}\n </span>\n );\n }\n\n const resolved = resolveWikiTarget(rawTarget, currentFile);\n const files = filesMetadata ?? {};\n const loaded = Object.keys(files).length > 0;\n\n // `resolved === undefined` ⇒ a relative target with no known current file: route\n // it optimistically (can't check existence or self-ness generically).\n if (resolved !== undefined) {\n if (currentFile && resolved === currentFile) {\n return (\n <span className=\"ir-wikilink ir-wikilink-self\" data-state=\"self\" {...rest}>\n {text}\n </span>\n );\n }\n const exists = !loaded || resolved in files; // optimistic until loaded\n if (!exists) {\n return (\n <span\n className=\"ir-wikilink ir-wikilink-broken\"\n data-state=\"broken\"\n title={`No file at ${resolved}`}\n {...rest}\n >\n {text}\n </span>\n );\n }\n }\n return (\n <Link href={rawTarget} className=\"ir-wikilink\" data-state=\"resolved\" {...rest}>\n {text}\n </Link>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA0FM;AA1FN,mBAA+B;AAC/B,kBAAqB;AACrB,qBAA+C;AAC/C,+BAAkC;AAGlC,MAAM,kBAAkB,CAAC,WAA2B;AAClD,QAAM,OAAO,OAAO,MAAM,OAAO,EAAE,IAAI,KAAK;AAC5C,SAAO,KAAK,QAAQ,YAAY,EAAE,KAAK;AACzC;AAGA,MAAM,YAAY,CAAC,SAAyB;AAC1C,QAAM,MAAgB,CAAC;AACvB,aAAW,OAAO,KAAK,MAAM,GAAG,GAAG;AACjC,QAAI,QAAQ,MAAM,QAAQ,IAAK;AAC/B,QAAI,QAAQ,KAAM,KAAI,IAAI;AAAA,QACrB,KAAI,KAAK,GAAG;AAAA,EACnB;AACA,SAAO,MAAM,IAAI,KAAK,GAAG;AAC3B;AASA,MAAM,oBAAoB,CAAC,QAAgB,gBAA6C;AACtF,MAAI,OAAO,WAAW,GAAG,EAAG,QAAO,UAAU,MAAM;AACnD,MAAI,CAAC,YAAa,QAAO;AACzB,QAAM,MAAM,YAAY,MAAM,GAAG,YAAY,YAAY,GAAG,CAAC;AAC7D,SAAO,UAAU,GAAG,GAAG,IAAI,MAAM,EAAE;AACrC;AAmCO,MAAM,WAAW,CAAC;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAI+E;AAC7E,QAAM,EAAE,cAAc,QAAI,kBAAI,0CAAiB;AAC/C,QAAM,oBAAgB,kBAAI,6CAA8B;AACxD,QAAM,cAAc,eAAe,mBAAmB,YAAY,QAAQ;AAE1E,QAAM,YAAY,UAAU;AAC5B,QAAM,OAAO,YAAY,UAAU,YAAY,gBAAgB,SAAS,IAAI;AAI5E,MAAI,CAAC,WAAW;AACd,WACE,4CAAC,UAAK,WAAU,eAAe,GAAG,MAC/B,gBACH;AAAA,EAEJ;AAEA,QAAM,WAAW,kBAAkB,WAAW,WAAW;AACzD,QAAM,QAAQ,iBAAiB,CAAC;AAChC,QAAM,SAAS,OAAO,KAAK,KAAK,EAAE,SAAS;AAI3C,MAAI,aAAa,QAAW;AAC1B,QAAI,eAAe,aAAa,aAAa;AAC3C,aACE,4CAAC,UAAK,WAAU,gCAA+B,cAAW,QAAQ,GAAG,MAClE,gBACH;AAAA,IAEJ;AACA,UAAM,SAAS,CAAC,UAAU,YAAY;AACtC,QAAI,CAAC,QAAQ;AACX,aACE;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,cAAW;AAAA,UACX,OAAO,cAAc,QAAQ;AAAA,UAC5B,GAAG;AAAA,UAEH;AAAA;AAAA,MACH;AAAA,IAEJ;AAAA,EACF;AACA,SACE,4CAAC,oBAAK,MAAM,WAAW,WAAU,eAAc,cAAW,YAAY,GAAG,MACtE,gBACH;AAEJ;","names":[]}
|
|
@@ -2,23 +2,36 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Default MDX `WikiLink` component — the render target for the `[[target]]` /
|
|
5
|
-
* `[[label|target]]` wiki-link syntax
|
|
5
|
+
* `[[label|target]]` wiki-link syntax. The transpiler remark plugin (R3-153)
|
|
6
6
|
* compiles that syntax to `<WikiLink target="…" label="…">`, carrying the raw
|
|
7
|
-
* target verbatim; resolution lives here
|
|
8
|
-
* §13.2).
|
|
7
|
+
* target/label verbatim; **resolution lives here** (MARKDOWN_SYNTAX_SPEC §13.2).
|
|
9
8
|
*
|
|
10
9
|
* Registered in {@link DEFAULT_MDX_COMPONENTS} so wiki-links render even in a
|
|
11
10
|
* plain-markdown repo (§11.2 phantom defaults). Targets are **paths only** —
|
|
12
|
-
* relative (resolved against the current file
|
|
11
|
+
* relative (resolved against the current file's directory) or absolute — with
|
|
13
12
|
* **no implicit search path** (§13.3, a deliberate departure from Obsidian).
|
|
14
|
-
* Routes through {@link Link}, so a same-app path navigates in-app and an
|
|
15
|
-
* external href renders as a plain `<a>`.
|
|
16
13
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
14
|
+
* The **current file** — the one the link is *authored in* — is read from the
|
|
15
|
+
* ambient `<Include>` render context. Every MDX file renders through `<Include>`
|
|
16
|
+
* (`FileRouter` renders even the top-level file that way), and Include publishes
|
|
17
|
+
* the rendered module's `EvaluationContext` to its subtree via
|
|
18
|
+
* {@link RenderExportedComponentContext}; the nearest one's
|
|
19
|
+
* `evaluation.module.filepath` is this file's own `/app/…` path. Because that
|
|
20
|
+
* context nests with each `<Include>`, a relative target inside an included
|
|
21
|
+
* fragment resolves against the **fragment**, not the top-level page in the URL.
|
|
22
|
+
*
|
|
23
|
+
* The resolved path is checked for **existence** against the live metadata store
|
|
24
|
+
* (keyed by absolute `/app/…` paths) for the three states (§13.3):
|
|
25
|
+
* - **self** — the resolved path is the current file: inert text, no link.
|
|
26
|
+
* - **broken** — no file at the resolved path (and the store has loaded): rendered
|
|
27
|
+
* as marked text, **not** a throw.
|
|
28
|
+
* - **resolved** — routed through {@link Link} (in-app navigation for a same-app
|
|
29
|
+
* href, a plain `<a>` otherwise).
|
|
30
|
+
*
|
|
31
|
+
* The check is **optimistic until the metadata store loads** (an empty store never
|
|
32
|
+
* flashes "broken"), and a relative target with no ambient render context (MDX
|
|
33
|
+
* rendered outside `<Include>`) routes optimistically. Such an app overrides this
|
|
34
|
+
* component (§11) for precise resolution.
|
|
22
35
|
*/
|
|
23
36
|
declare const WikiLink: ({ target, label, children, ...rest }: {
|
|
24
37
|
target?: string;
|
|
@@ -2,23 +2,36 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Default MDX `WikiLink` component — the render target for the `[[target]]` /
|
|
5
|
-
* `[[label|target]]` wiki-link syntax
|
|
5
|
+
* `[[label|target]]` wiki-link syntax. The transpiler remark plugin (R3-153)
|
|
6
6
|
* compiles that syntax to `<WikiLink target="…" label="…">`, carrying the raw
|
|
7
|
-
* target verbatim; resolution lives here
|
|
8
|
-
* §13.2).
|
|
7
|
+
* target/label verbatim; **resolution lives here** (MARKDOWN_SYNTAX_SPEC §13.2).
|
|
9
8
|
*
|
|
10
9
|
* Registered in {@link DEFAULT_MDX_COMPONENTS} so wiki-links render even in a
|
|
11
10
|
* plain-markdown repo (§11.2 phantom defaults). Targets are **paths only** —
|
|
12
|
-
* relative (resolved against the current file
|
|
11
|
+
* relative (resolved against the current file's directory) or absolute — with
|
|
13
12
|
* **no implicit search path** (§13.3, a deliberate departure from Obsidian).
|
|
14
|
-
* Routes through {@link Link}, so a same-app path navigates in-app and an
|
|
15
|
-
* external href renders as a plain `<a>`.
|
|
16
13
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
14
|
+
* The **current file** — the one the link is *authored in* — is read from the
|
|
15
|
+
* ambient `<Include>` render context. Every MDX file renders through `<Include>`
|
|
16
|
+
* (`FileRouter` renders even the top-level file that way), and Include publishes
|
|
17
|
+
* the rendered module's `EvaluationContext` to its subtree via
|
|
18
|
+
* {@link RenderExportedComponentContext}; the nearest one's
|
|
19
|
+
* `evaluation.module.filepath` is this file's own `/app/…` path. Because that
|
|
20
|
+
* context nests with each `<Include>`, a relative target inside an included
|
|
21
|
+
* fragment resolves against the **fragment**, not the top-level page in the URL.
|
|
22
|
+
*
|
|
23
|
+
* The resolved path is checked for **existence** against the live metadata store
|
|
24
|
+
* (keyed by absolute `/app/…` paths) for the three states (§13.3):
|
|
25
|
+
* - **self** — the resolved path is the current file: inert text, no link.
|
|
26
|
+
* - **broken** — no file at the resolved path (and the store has loaded): rendered
|
|
27
|
+
* as marked text, **not** a throw.
|
|
28
|
+
* - **resolved** — routed through {@link Link} (in-app navigation for a same-app
|
|
29
|
+
* href, a plain `<a>` otherwise).
|
|
30
|
+
*
|
|
31
|
+
* The check is **optimistic until the metadata store loads** (an empty store never
|
|
32
|
+
* flashes "broken"), and a relative target with no ambient render context (MDX
|
|
33
|
+
* rendered outside `<Include>`) routes optimistically. Such an app overrides this
|
|
34
|
+
* component (§11) for precise resolution.
|
|
22
35
|
*/
|
|
23
36
|
declare const WikiLink: ({ target, label, children, ...rest }: {
|
|
24
37
|
target?: string;
|
|
@@ -1,18 +1,63 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { use } from "react";
|
|
2
3
|
import { Link } from "./Link";
|
|
4
|
+
import { RenderExportedComponentContext } from "./Include";
|
|
5
|
+
import { TinkerableContext } from "../TinkerableContext";
|
|
3
6
|
const labelFromTarget = (target) => {
|
|
4
7
|
const base = target.split(/[\\/]/).pop() ?? target;
|
|
5
8
|
return base.replace(/\.mdx?$/i, "") || target;
|
|
6
9
|
};
|
|
10
|
+
const normalize = (path) => {
|
|
11
|
+
const out = [];
|
|
12
|
+
for (const seg of path.split("/")) {
|
|
13
|
+
if (seg === "" || seg === ".") continue;
|
|
14
|
+
if (seg === "..") out.pop();
|
|
15
|
+
else out.push(seg);
|
|
16
|
+
}
|
|
17
|
+
return "/" + out.join("/");
|
|
18
|
+
};
|
|
19
|
+
const resolveWikiTarget = (target, currentFile) => {
|
|
20
|
+
if (target.startsWith("/")) return normalize(target);
|
|
21
|
+
if (!currentFile) return void 0;
|
|
22
|
+
const dir = currentFile.slice(0, currentFile.lastIndexOf("/"));
|
|
23
|
+
return normalize(`${dir}/${target}`);
|
|
24
|
+
};
|
|
7
25
|
const WikiLink = ({
|
|
8
26
|
target,
|
|
9
27
|
label,
|
|
10
28
|
children,
|
|
11
29
|
...rest
|
|
12
30
|
}) => {
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
31
|
+
const { filesMetadata } = use(TinkerableContext);
|
|
32
|
+
const renderContext = use(RenderExportedComponentContext);
|
|
33
|
+
const currentFile = renderContext?.evaluationContext?.evaluation?.module?.filepath;
|
|
34
|
+
const rawTarget = target ?? "";
|
|
35
|
+
const text = children ?? label ?? (rawTarget ? labelFromTarget(rawTarget) : "");
|
|
36
|
+
if (!rawTarget) {
|
|
37
|
+
return /* @__PURE__ */ jsx("span", { className: "ir-wikilink", ...rest, children: text });
|
|
38
|
+
}
|
|
39
|
+
const resolved = resolveWikiTarget(rawTarget, currentFile);
|
|
40
|
+
const files = filesMetadata ?? {};
|
|
41
|
+
const loaded = Object.keys(files).length > 0;
|
|
42
|
+
if (resolved !== void 0) {
|
|
43
|
+
if (currentFile && resolved === currentFile) {
|
|
44
|
+
return /* @__PURE__ */ jsx("span", { className: "ir-wikilink ir-wikilink-self", "data-state": "self", ...rest, children: text });
|
|
45
|
+
}
|
|
46
|
+
const exists = !loaded || resolved in files;
|
|
47
|
+
if (!exists) {
|
|
48
|
+
return /* @__PURE__ */ jsx(
|
|
49
|
+
"span",
|
|
50
|
+
{
|
|
51
|
+
className: "ir-wikilink ir-wikilink-broken",
|
|
52
|
+
"data-state": "broken",
|
|
53
|
+
title: `No file at ${resolved}`,
|
|
54
|
+
...rest,
|
|
55
|
+
children: text
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return /* @__PURE__ */ jsx(Link, { href: rawTarget, className: "ir-wikilink", "data-state": "resolved", ...rest, children: text });
|
|
16
61
|
};
|
|
17
62
|
export {
|
|
18
63
|
WikiLink
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/WikiLink.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport { Link } from './Link';\n\n/** Derive a human label from a target path: basename without the extension. */\nconst labelFromTarget = (target: string): string => {\n const base = target.split(/[\\\\/]/).pop() ?? target;\n return base.replace(/\\.mdx?$/i, '') || target;\n};\n\n/**\n * Default MDX `WikiLink` component — the render target for the `[[target]]` /\n * `[[label|target]]` wiki-link syntax
|
|
1
|
+
{"version":3,"sources":["../../src/components/WikiLink.tsx"],"sourcesContent":["import { ReactNode, use } from 'react';\nimport { Link } from './Link';\nimport { RenderExportedComponentContext } from './Include';\nimport { TinkerableContext } from '../TinkerableContext';\n\n/** Derive a human label from a target path: basename without the extension. */\nconst labelFromTarget = (target: string): string => {\n const base = target.split(/[\\\\/]/).pop() ?? target;\n return base.replace(/\\.mdx?$/i, '') || target;\n};\n\n/** Collapse `.`/`..`/empty segments into a clean absolute path. */\nconst normalize = (path: string): string => {\n const out: string[] = [];\n for (const seg of path.split('/')) {\n if (seg === '' || seg === '.') continue;\n if (seg === '..') out.pop();\n else out.push(seg);\n }\n return '/' + out.join('/');\n};\n\n/**\n * Resolve a wiki-link target to an absolute sandbox path, or `undefined` when it\n * cannot be resolved (a relative target with no known current file). An\n * **absolute** target (`/…`) is taken verbatim; a **relative** target resolves\n * against the current file's directory. Pure path arithmetic (MARKDOWN_SYNTAX_SPEC\n * §13.2) — it never touches the filesystem or any other file.\n */\nconst resolveWikiTarget = (target: string, currentFile?: string): string | undefined => {\n if (target.startsWith('/')) return normalize(target);\n if (!currentFile) return undefined;\n const dir = currentFile.slice(0, currentFile.lastIndexOf('/'));\n return normalize(`${dir}/${target}`);\n};\n\n/**\n * Default MDX `WikiLink` component — the render target for the `[[target]]` /\n * `[[label|target]]` wiki-link syntax. The transpiler remark plugin (R3-153)\n * compiles that syntax to `<WikiLink target=\"…\" label=\"…\">`, carrying the raw\n * target/label verbatim; **resolution lives here** (MARKDOWN_SYNTAX_SPEC §13.2).\n *\n * Registered in {@link DEFAULT_MDX_COMPONENTS} so wiki-links render even in a\n * plain-markdown repo (§11.2 phantom defaults). Targets are **paths only** —\n * relative (resolved against the current file's directory) or absolute — with\n * **no implicit search path** (§13.3, a deliberate departure from Obsidian).\n *\n * The **current file** — the one the link is *authored in* — is read from the\n * ambient `<Include>` render context. Every MDX file renders through `<Include>`\n * (`FileRouter` renders even the top-level file that way), and Include publishes\n * the rendered module's `EvaluationContext` to its subtree via\n * {@link RenderExportedComponentContext}; the nearest one's\n * `evaluation.module.filepath` is this file's own `/app/…` path. Because that\n * context nests with each `<Include>`, a relative target inside an included\n * fragment resolves against the **fragment**, not the top-level page in the URL.\n *\n * The resolved path is checked for **existence** against the live metadata store\n * (keyed by absolute `/app/…` paths) for the three states (§13.3):\n * - **self** — the resolved path is the current file: inert text, no link.\n * - **broken** — no file at the resolved path (and the store has loaded): rendered\n * as marked text, **not** a throw.\n * - **resolved** — routed through {@link Link} (in-app navigation for a same-app\n * href, a plain `<a>` otherwise).\n *\n * The check is **optimistic until the metadata store loads** (an empty store never\n * flashes \"broken\"), and a relative target with no ambient render context (MDX\n * rendered outside `<Include>`) routes optimistically. Such an app overrides this\n * component (§11) for precise resolution.\n */\nexport const WikiLink = ({\n target,\n label,\n children,\n ...rest\n}: {\n target?: string;\n label?: ReactNode;\n children?: ReactNode;\n} & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>): ReactNode => {\n const { filesMetadata } = use(TinkerableContext);\n const renderContext = use(RenderExportedComponentContext);\n const currentFile = renderContext?.evaluationContext?.evaluation?.module?.filepath;\n\n const rawTarget = target ?? '';\n const text = children ?? label ?? (rawTarget ? labelFromTarget(rawTarget) : '');\n\n // Defensive: the kernel never emits an empty target, but a hand-written\n // `<WikiLink>` might. Render inert text rather than a link to nowhere.\n if (!rawTarget) {\n return (\n <span className=\"ir-wikilink\" {...rest}>\n {text}\n </span>\n );\n }\n\n const resolved = resolveWikiTarget(rawTarget, currentFile);\n const files = filesMetadata ?? {};\n const loaded = Object.keys(files).length > 0;\n\n // `resolved === undefined` ⇒ a relative target with no known current file: route\n // it optimistically (can't check existence or self-ness generically).\n if (resolved !== undefined) {\n if (currentFile && resolved === currentFile) {\n return (\n <span className=\"ir-wikilink ir-wikilink-self\" data-state=\"self\" {...rest}>\n {text}\n </span>\n );\n }\n const exists = !loaded || resolved in files; // optimistic until loaded\n if (!exists) {\n return (\n <span\n className=\"ir-wikilink ir-wikilink-broken\"\n data-state=\"broken\"\n title={`No file at ${resolved}`}\n {...rest}\n >\n {text}\n </span>\n );\n }\n }\n return (\n <Link href={rawTarget} className=\"ir-wikilink\" data-state=\"resolved\" {...rest}>\n {text}\n </Link>\n );\n};\n"],"mappings":"AA0FM;AA1FN,SAAoB,WAAW;AAC/B,SAAS,YAAY;AACrB,SAAS,sCAAsC;AAC/C,SAAS,yBAAyB;AAGlC,MAAM,kBAAkB,CAAC,WAA2B;AAClD,QAAM,OAAO,OAAO,MAAM,OAAO,EAAE,IAAI,KAAK;AAC5C,SAAO,KAAK,QAAQ,YAAY,EAAE,KAAK;AACzC;AAGA,MAAM,YAAY,CAAC,SAAyB;AAC1C,QAAM,MAAgB,CAAC;AACvB,aAAW,OAAO,KAAK,MAAM,GAAG,GAAG;AACjC,QAAI,QAAQ,MAAM,QAAQ,IAAK;AAC/B,QAAI,QAAQ,KAAM,KAAI,IAAI;AAAA,QACrB,KAAI,KAAK,GAAG;AAAA,EACnB;AACA,SAAO,MAAM,IAAI,KAAK,GAAG;AAC3B;AASA,MAAM,oBAAoB,CAAC,QAAgB,gBAA6C;AACtF,MAAI,OAAO,WAAW,GAAG,EAAG,QAAO,UAAU,MAAM;AACnD,MAAI,CAAC,YAAa,QAAO;AACzB,QAAM,MAAM,YAAY,MAAM,GAAG,YAAY,YAAY,GAAG,CAAC;AAC7D,SAAO,UAAU,GAAG,GAAG,IAAI,MAAM,EAAE;AACrC;AAmCO,MAAM,WAAW,CAAC;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAI+E;AAC7E,QAAM,EAAE,cAAc,IAAI,IAAI,iBAAiB;AAC/C,QAAM,gBAAgB,IAAI,8BAA8B;AACxD,QAAM,cAAc,eAAe,mBAAmB,YAAY,QAAQ;AAE1E,QAAM,YAAY,UAAU;AAC5B,QAAM,OAAO,YAAY,UAAU,YAAY,gBAAgB,SAAS,IAAI;AAI5E,MAAI,CAAC,WAAW;AACd,WACE,oBAAC,UAAK,WAAU,eAAe,GAAG,MAC/B,gBACH;AAAA,EAEJ;AAEA,QAAM,WAAW,kBAAkB,WAAW,WAAW;AACzD,QAAM,QAAQ,iBAAiB,CAAC;AAChC,QAAM,SAAS,OAAO,KAAK,KAAK,EAAE,SAAS;AAI3C,MAAI,aAAa,QAAW;AAC1B,QAAI,eAAe,aAAa,aAAa;AAC3C,aACE,oBAAC,UAAK,WAAU,gCAA+B,cAAW,QAAQ,GAAG,MAClE,gBACH;AAAA,IAEJ;AACA,UAAM,SAAS,CAAC,UAAU,YAAY;AACtC,QAAI,CAAC,QAAQ;AACX,aACE;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,cAAW;AAAA,UACX,OAAO,cAAc,QAAQ;AAAA,UAC5B,GAAG;AAAA,UAEH;AAAA;AAAA,MACH;AAAA,IAEJ;AAAA,EACF;AACA,SACE,oBAAC,QAAK,MAAM,WAAW,WAAU,eAAc,cAAW,YAAY,GAAG,MACtE,gBACH;AAEJ;","names":[]}
|
package/dist/version.cjs
CHANGED
|
@@ -21,7 +21,7 @@ __export(version_exports, {
|
|
|
21
21
|
SDK_VERSION: () => SDK_VERSION
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(version_exports);
|
|
24
|
-
const SDK_VERSION = "0.
|
|
24
|
+
const SDK_VERSION = "0.24.0";
|
|
25
25
|
// Annotate the CommonJS export names for ESM import in node:
|
|
26
26
|
0 && (module.exports = {
|
|
27
27
|
SDK_VERSION
|
package/dist/version.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.24.0';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,MAAM,cAAc;","names":[]}
|
package/dist/version.d.cts
CHANGED
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.24.0';\n"],"mappings":"AAIO,MAAM,cAAc;","names":[]}
|
package/package.json
CHANGED