@scalar/api-reference 1.48.8 → 1.49.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 +33 -0
- package/dist/browser/standalone.js +9866 -9838
- package/dist/browser/webpack-stats.json +1 -1
- package/dist/components/ApiReference.vue.d.ts.map +1 -1
- package/dist/components/ApiReference.vue.js +1 -1
- package/dist/components/ApiReference.vue2.js +2 -4
- package/dist/components/Content/Content.vue.d.ts +2 -4
- package/dist/components/Content/Content.vue.d.ts.map +1 -1
- package/dist/components/Content/Content.vue.js +77 -83
- package/dist/components/Content/Models/ModelTag.vue.d.ts +3 -3
- package/dist/components/Content/Models/ModelTag.vue.d.ts.map +1 -1
- package/dist/components/Content/Models/ModelTag.vue.js +42 -48
- package/dist/components/Content/Operations/TraversedEntry.vue.d.ts.map +1 -1
- package/dist/components/Content/Operations/TraversedEntry.vue.js +3 -2
- package/dist/components/Content/Schema/SchemaProperty.vue.d.ts.map +1 -1
- package/dist/components/Content/Schema/SchemaProperty.vue.js +1 -1
- package/dist/components/Content/Schema/SchemaProperty.vue2.js +9 -1
- package/dist/components/Content/Schema/helpers/should-display-description.js +1 -1
- package/dist/components/Content/Tags/components/ModernLayout.vue.d.ts +2 -2
- package/dist/components/Content/Tags/components/ModernLayout.vue.d.ts.map +1 -1
- package/dist/components/Content/Tags/components/ModernLayout.vue.js +1 -1
- package/dist/components/Content/Tags/components/ModernLayout.vue2.js +18 -26
- package/dist/components/Lazy/Lazy.vue.d.ts +3 -0
- package/dist/components/Lazy/Lazy.vue.d.ts.map +1 -1
- package/dist/components/Lazy/Lazy.vue.js +93 -4
- package/dist/features/ask-agent-button/AskAgentButton.vue.d.ts.map +1 -1
- package/dist/features/ask-agent-button/AskAgentButton.vue.js +1 -1
- package/dist/features/ask-agent-button/AskAgentButton.vue2.js +18 -14
- package/dist/helpers/id-routing.d.ts +4 -0
- package/dist/helpers/id-routing.d.ts.map +1 -1
- package/dist/helpers/id-routing.js +51 -5
- package/dist/helpers/lazy-bus.d.ts +19 -19
- package/dist/helpers/lazy-bus.d.ts.map +1 -1
- package/dist/helpers/lazy-bus.js +63 -28
- package/dist/style.css +126 -124
- package/package.json +11 -11
|
@@ -1,14 +1,103 @@
|
|
|
1
|
-
import { defineComponent, renderSlot, createCommentVNode
|
|
2
|
-
import {
|
|
1
|
+
import { defineComponent, ref, computed, onMounted, watch, nextTick, onBeforeUnmount, createElementBlock, openBlock, normalizeStyle, renderSlot, createCommentVNode } from "vue";
|
|
2
|
+
import { useIntersectionObserver } from "@vueuse/core";
|
|
3
|
+
import { useLazyBus, getLazyPlaceholderHeight, requestLazyRender, setLazyPlaceholderHeight } from "../../helpers/lazy-bus.js";
|
|
4
|
+
const _hoisted_1 = ["id", "data-placeholder"];
|
|
5
|
+
const PLACEHOLDER_HEIGHT_PX = 760;
|
|
6
|
+
const VIEWPORT_OVERSCAN_PX = 1200;
|
|
3
7
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
4
8
|
__name: "Lazy",
|
|
5
9
|
props: {
|
|
6
|
-
id: {}
|
|
10
|
+
id: {},
|
|
11
|
+
expanded: { type: Boolean, default: false }
|
|
7
12
|
},
|
|
8
13
|
setup(__props) {
|
|
14
|
+
const VIEWPORT_ROOT_MARGIN = `${VIEWPORT_OVERSCAN_PX}px 0px`;
|
|
9
15
|
const { isReady } = useLazyBus(__props.id);
|
|
16
|
+
const lazyContainerRef = ref(null);
|
|
17
|
+
const placeholderHeight = ref(
|
|
18
|
+
getLazyPlaceholderHeight(__props.id) ?? PLACEHOLDER_HEIGHT_PX
|
|
19
|
+
);
|
|
20
|
+
let contentResizeObserver = null;
|
|
21
|
+
const shouldRender = computed(() => isReady.value || __props.expanded);
|
|
22
|
+
onMounted(() => {
|
|
23
|
+
if (typeof window === "undefined") {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (!("IntersectionObserver" in window)) {
|
|
27
|
+
requestLazyRender(__props.id, true);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
useIntersectionObserver(
|
|
31
|
+
lazyContainerRef,
|
|
32
|
+
([entry]) => {
|
|
33
|
+
if (entry?.isIntersecting && !isReady.value) {
|
|
34
|
+
requestLazyRender(__props.id, true);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{ rootMargin: VIEWPORT_ROOT_MARGIN }
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
watch(
|
|
41
|
+
() => shouldRender.value,
|
|
42
|
+
(rendered, wasRendered) => {
|
|
43
|
+
if (wasRendered && !rendered && lazyContainerRef.value) {
|
|
44
|
+
const h = lazyContainerRef.value.offsetHeight;
|
|
45
|
+
if (Number.isFinite(h) && h > 0) {
|
|
46
|
+
placeholderHeight.value = h;
|
|
47
|
+
setLazyPlaceholderHeight(__props.id, h);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{ flush: "pre" }
|
|
52
|
+
);
|
|
53
|
+
watch(
|
|
54
|
+
() => shouldRender.value,
|
|
55
|
+
(rendered) => {
|
|
56
|
+
if (!rendered) {
|
|
57
|
+
contentResizeObserver?.disconnect();
|
|
58
|
+
contentResizeObserver = null;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
void nextTick(() => {
|
|
62
|
+
if (!lazyContainerRef.value || typeof ResizeObserver === "undefined") {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (!contentResizeObserver) {
|
|
66
|
+
contentResizeObserver = new ResizeObserver(() => {
|
|
67
|
+
if (!lazyContainerRef.value) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const h2 = lazyContainerRef.value.offsetHeight;
|
|
71
|
+
if (Number.isFinite(h2) && h2 > 0) {
|
|
72
|
+
placeholderHeight.value = h2;
|
|
73
|
+
setLazyPlaceholderHeight(__props.id, h2);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
contentResizeObserver.observe(lazyContainerRef.value);
|
|
78
|
+
const h = lazyContainerRef.value.offsetHeight;
|
|
79
|
+
if (Number.isFinite(h) && h > 0) {
|
|
80
|
+
placeholderHeight.value = h;
|
|
81
|
+
setLazyPlaceholderHeight(__props.id, h);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
{ immediate: true }
|
|
86
|
+
);
|
|
87
|
+
onBeforeUnmount(() => {
|
|
88
|
+
contentResizeObserver?.disconnect();
|
|
89
|
+
});
|
|
10
90
|
return (_ctx, _cache) => {
|
|
11
|
-
return
|
|
91
|
+
return openBlock(), createElementBlock("div", {
|
|
92
|
+
id: !shouldRender.value ? __props.id : void 0,
|
|
93
|
+
ref_key: "lazyContainerRef",
|
|
94
|
+
ref: lazyContainerRef,
|
|
95
|
+
"data-placeholder": !shouldRender.value,
|
|
96
|
+
"data-testid": "lazy-container",
|
|
97
|
+
style: normalizeStyle({ height: shouldRender.value ? void 0 : `${placeholderHeight.value}px` })
|
|
98
|
+
}, [
|
|
99
|
+
shouldRender.value ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("", true)
|
|
100
|
+
], 12, _hoisted_1);
|
|
12
101
|
};
|
|
13
102
|
}
|
|
14
103
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AskAgentButton.vue.d.ts","sourceRoot":"","sources":["../../../src/features/ask-agent-button/AskAgentButton.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AskAgentButton.vue.d.ts","sourceRoot":"","sources":["../../../src/features/ask-agent-button/AskAgentButton.vue"],"names":[],"mappings":"AAoQA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./AskAgentButton.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const AskAgentButton = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const AskAgentButton = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-78f5377c"]]);
|
|
5
5
|
export {
|
|
6
6
|
AskAgentButton as default
|
|
7
7
|
};
|
|
@@ -1,44 +1,48 @@
|
|
|
1
|
-
import { defineComponent, ref, createElementBlock, createCommentVNode, unref, openBlock,
|
|
1
|
+
import { defineComponent, ref, createElementBlock, createCommentVNode, unref, openBlock, withModifiers, createVNode, createElementVNode, withDirectives, normalizeClass, vModelText } from "vue";
|
|
2
2
|
import { ScalarIconSparkle, ScalarIconArrowUp } from "@scalar/icons";
|
|
3
3
|
import { useAgentContext } from "../../hooks/use-agent.js";
|
|
4
4
|
const _hoisted_1 = {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
class: "ask-agent-scalar-send",
|
|
6
|
+
type: "submit"
|
|
7
7
|
};
|
|
8
8
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
9
9
|
__name: "AskAgentButton",
|
|
10
10
|
setup(__props) {
|
|
11
11
|
const agentContext = useAgentContext();
|
|
12
12
|
const message = ref("");
|
|
13
|
+
const inputRef = ref();
|
|
13
14
|
function handleSubmit() {
|
|
14
15
|
agentContext.value?.openAgent(message.value);
|
|
15
16
|
message.value = "";
|
|
16
17
|
}
|
|
17
18
|
return (_ctx, _cache) => {
|
|
18
|
-
return unref(agentContext)?.agentEnabled.value ? (openBlock(), createElementBlock("
|
|
19
|
+
return unref(agentContext)?.agentEnabled.value ? (openBlock(), createElementBlock("form", {
|
|
20
|
+
key: 0,
|
|
21
|
+
class: "agent-button-container",
|
|
22
|
+
onClick: _cache[1] || (_cache[1] = ($event) => inputRef.value?.focus()),
|
|
23
|
+
onSubmit: _cache[2] || (_cache[2] = withModifiers(($event) => handleSubmit(), ["prevent"]))
|
|
24
|
+
}, [
|
|
19
25
|
createVNode(unref(ScalarIconSparkle), {
|
|
20
26
|
class: "size-3 shrink-0",
|
|
21
27
|
weight: "fill"
|
|
22
28
|
}),
|
|
29
|
+
_cache[3] || (_cache[3] = createElementVNode("div", { class: "ask-agent-scalar-input-label" }, "Ask AI Agent", -1)),
|
|
23
30
|
withDirectives(createElementVNode("input", {
|
|
31
|
+
ref_key: "inputRef",
|
|
32
|
+
ref: inputRef,
|
|
24
33
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => message.value = $event),
|
|
25
|
-
class: "ask-agent-scalar-input",
|
|
26
|
-
placeholder: "Ask AI Agent"
|
|
27
|
-
|
|
28
|
-
}, null, 544), [
|
|
34
|
+
class: normalizeClass(["ask-agent-scalar-input", { "ask-agent-scalar-input-not-empty": message.value.length > 0 }]),
|
|
35
|
+
placeholder: "Ask AI Agent"
|
|
36
|
+
}, null, 2), [
|
|
29
37
|
[vModelText, message.value]
|
|
30
38
|
]),
|
|
31
|
-
createElementVNode("button",
|
|
32
|
-
class: "ask-agent-scalar-send",
|
|
33
|
-
type: "button",
|
|
34
|
-
onClick: _cache[2] || (_cache[2] = ($event) => handleSubmit())
|
|
35
|
-
}, [
|
|
39
|
+
createElementVNode("button", _hoisted_1, [
|
|
36
40
|
createVNode(unref(ScalarIconArrowUp), {
|
|
37
41
|
class: "size-3",
|
|
38
42
|
weight: "bold"
|
|
39
43
|
})
|
|
40
44
|
])
|
|
41
|
-
])) : createCommentVNode("", true);
|
|
45
|
+
], 32)) : createCommentVNode("", true);
|
|
42
46
|
};
|
|
43
47
|
}
|
|
44
48
|
});
|
|
@@ -3,6 +3,10 @@ export declare const sanitizeBasePath: (basePath: string) => string;
|
|
|
3
3
|
export declare const getIdFromHash: (location: string | URL, slugPrefix: string | undefined) => string;
|
|
4
4
|
/** Extracts an element id from the path when using path routing */
|
|
5
5
|
export declare const getIdFromPath: (location: string | URL, basePath: string, slugPrefix: string | undefined) => string;
|
|
6
|
+
/** Extracts an element id from a hash-prefixed basePath */
|
|
7
|
+
export declare const getIdFromHashBasePath: (location: string | URL, basePath: string, slugPrefix: string | undefined) => string;
|
|
8
|
+
/** Determines whether a URL matches the provided basePath. */
|
|
9
|
+
export declare const matchesBasePath: (location: string | URL, basePath: string) => boolean;
|
|
6
10
|
/**
|
|
7
11
|
* Extracts a navigation id from a URL based on the routing type
|
|
8
12
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id-routing.d.ts","sourceRoot":"","sources":["../../src/helpers/id-routing.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,WAEhD,CAAA;
|
|
1
|
+
{"version":3,"file":"id-routing.d.ts","sourceRoot":"","sources":["../../src/helpers/id-routing.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,WAEhD,CAAA;AAwBD,mEAAmE;AACnE,eAAO,MAAM,aAAa,GAAI,UAAU,MAAM,GAAG,GAAG,EAAE,YAAY,MAAM,GAAG,SAAS,WAMnF,CAAA;AACD,mEAAmE;AACnE,eAAO,MAAM,aAAa,GAAI,UAAU,MAAM,GAAG,GAAG,EAAE,UAAU,MAAM,EAAE,YAAY,MAAM,GAAG,SAAS,WAqBrG,CAAA;AAED,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,GAAG,GAAG,EAAE,UAAU,MAAM,EAAE,YAAY,MAAM,GAAG,SAAS,WAW7G,CAAA;AAED,8DAA8D;AAC9D,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,GAAG,GAAG,EAAE,UAAU,MAAM,YAiBvE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,GAAG,GAAG,EAAE,UAAU,MAAM,GAAG,SAAS,EAAE,YAAY,MAAM,GAAG,SAAS,WAQ3G,CAAA;AAmBD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,GAAG,SAAS,EAAE,iBAAiB,OAAO,oBAsBhG,CAAA;AAED,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,GAAI,IAAI,MAAM,KAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAajF,CAAA"}
|
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
const sanitizeBasePath = (basePath) => {
|
|
2
2
|
return basePath.replace(/^\/+|\/+$/g, "");
|
|
3
3
|
};
|
|
4
|
+
const isHashBasePath = (basePath) => basePath.startsWith("#");
|
|
5
|
+
const sanitizeHashBasePath = (basePath) => {
|
|
6
|
+
return basePath.replace(/^#+/, "").replace(/\/+$/g, "");
|
|
7
|
+
};
|
|
8
|
+
const applySlugPrefix = (base, slugPrefix) => {
|
|
9
|
+
return slugPrefix ? `${slugPrefix}${base ? "/" : ""}${base}` : base;
|
|
10
|
+
};
|
|
11
|
+
const stripBasePathPrefix = (value, basePath) => {
|
|
12
|
+
if (value === basePath) {
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
15
|
+
if (value.startsWith(`${basePath}/`)) {
|
|
16
|
+
return value.slice(basePath.length + 1);
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
4
20
|
const getIdFromHash = (location, slugPrefix) => {
|
|
5
21
|
const url = typeof location === "string" ? new URL(location) : location;
|
|
6
22
|
const base = decodeURIComponent(url.hash.slice(1));
|
|
7
|
-
return
|
|
23
|
+
return applySlugPrefix(base, slugPrefix);
|
|
8
24
|
};
|
|
9
25
|
const getIdFromPath = (location, basePath, slugPrefix) => {
|
|
10
26
|
const url = typeof location === "string" ? new URL(location) : location;
|
|
@@ -13,12 +29,35 @@ const getIdFromPath = (location, basePath, slugPrefix) => {
|
|
|
13
29
|
if (url.pathname.startsWith(basePathWithSlash)) {
|
|
14
30
|
const remainder = url.pathname.slice(basePathWithSlash.length);
|
|
15
31
|
const base = decodeURIComponent(remainder.startsWith("/") ? remainder.slice(1) : remainder);
|
|
16
|
-
return
|
|
32
|
+
return applySlugPrefix(base, slugPrefix);
|
|
17
33
|
}
|
|
18
34
|
return slugPrefix ?? "";
|
|
19
35
|
};
|
|
36
|
+
const getIdFromHashBasePath = (location, basePath, slugPrefix) => {
|
|
37
|
+
const url = typeof location === "string" ? new URL(location) : location;
|
|
38
|
+
const hash = decodeURIComponent(url.hash.slice(1));
|
|
39
|
+
const sanitized = sanitizeHashBasePath(basePath);
|
|
40
|
+
const remainder = stripBasePathPrefix(hash, sanitized);
|
|
41
|
+
if (remainder !== null) {
|
|
42
|
+
return applySlugPrefix(remainder, slugPrefix);
|
|
43
|
+
}
|
|
44
|
+
return slugPrefix ?? "";
|
|
45
|
+
};
|
|
46
|
+
const matchesBasePath = (location, basePath) => {
|
|
47
|
+
const url = typeof location === "string" ? new URL(location) : location;
|
|
48
|
+
if (isHashBasePath(basePath)) {
|
|
49
|
+
const hash = decodeURIComponent(url.hash);
|
|
50
|
+
return hash === basePath || hash.startsWith(`${basePath}/`);
|
|
51
|
+
}
|
|
52
|
+
const sanitized = sanitizeBasePath(basePath);
|
|
53
|
+
const basePathWithSlash = sanitized ? `/${sanitized.split("/").map((segment) => encodeURIComponent(segment)).join("/")}` : "";
|
|
54
|
+
return url.pathname === basePathWithSlash || url.pathname.startsWith(`${basePathWithSlash}/`);
|
|
55
|
+
};
|
|
20
56
|
const getIdFromUrl = (url, basePath, slugPrefix) => {
|
|
21
|
-
|
|
57
|
+
if (typeof basePath !== "string") {
|
|
58
|
+
return getIdFromHash(url, slugPrefix);
|
|
59
|
+
}
|
|
60
|
+
return isHashBasePath(basePath) ? getIdFromHashBasePath(url, basePath, slugPrefix) : getIdFromPath(url, basePath, slugPrefix);
|
|
22
61
|
};
|
|
23
62
|
const stripFirstSegment = (id) => {
|
|
24
63
|
const hasTrailingSlash = id.endsWith("/");
|
|
@@ -33,8 +72,13 @@ const makeUrlFromId = (_id, basePath, isMultiDocument) => {
|
|
|
33
72
|
const id = isMultiDocument ? _id : stripFirstSegment(_id);
|
|
34
73
|
const url = new URL(window.location.href);
|
|
35
74
|
if (typeof basePath === "string") {
|
|
36
|
-
|
|
37
|
-
|
|
75
|
+
if (isHashBasePath(basePath)) {
|
|
76
|
+
const base = sanitizeHashBasePath(basePath);
|
|
77
|
+
url.hash = [base, id].filter(Boolean).join("/");
|
|
78
|
+
} else {
|
|
79
|
+
const base = sanitizeBasePath(basePath);
|
|
80
|
+
url.pathname = `${base}/${id}`;
|
|
81
|
+
}
|
|
38
82
|
} else {
|
|
39
83
|
url.hash = id;
|
|
40
84
|
}
|
|
@@ -55,9 +99,11 @@ const getSchemaParamsFromId = (id) => {
|
|
|
55
99
|
};
|
|
56
100
|
export {
|
|
57
101
|
getIdFromHash,
|
|
102
|
+
getIdFromHashBasePath,
|
|
58
103
|
getIdFromPath,
|
|
59
104
|
getIdFromUrl,
|
|
60
105
|
getSchemaParamsFromId,
|
|
61
106
|
makeUrlFromId,
|
|
107
|
+
matchesBasePath,
|
|
62
108
|
sanitizeBasePath
|
|
63
109
|
};
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
/** Tracks when the initial load is complete.
|
|
2
|
-
* We will have placeholder content to allow the active item to be scrolled to the top while
|
|
3
|
-
* the rest of the content is loaded.
|
|
4
|
-
*/
|
|
1
|
+
/** Tracks when the initial load is complete. */
|
|
5
2
|
export declare const firstLazyLoadComplete: import("vue").Ref<boolean, boolean>;
|
|
3
|
+
export declare const getLazyPlaceholderHeight: (id: string) => number | undefined;
|
|
4
|
+
export declare const setLazyPlaceholderHeight: (id: string, height: number) => void;
|
|
6
5
|
type UnblockFn = () => void;
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Blocks intersection until the returned unblock callback is run.
|
|
8
|
+
* Prevents scroll jump while we render new lazy content.
|
|
10
9
|
*/
|
|
11
10
|
export declare const blockIntersection: () => UnblockFn;
|
|
12
11
|
/** If there are any pending blocking operations we disable intersection */
|
|
@@ -17,26 +16,27 @@ export declare const intersectionEnabled: import("vue").ComputedRef<boolean>;
|
|
|
17
16
|
* but processQueue will skip actual re-rendering for items already ready.
|
|
18
17
|
*/
|
|
19
18
|
export declare const addToPriorityQueue: (id: string | undefined) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Request an item to be rendered (e.g. when it re-enters the overscan zone).
|
|
21
|
+
*/
|
|
22
|
+
export declare const requestLazyRender: (id: string | undefined, priority?: boolean) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Schedules a single run of the lazy bus so that documents with no Lazy components
|
|
25
|
+
* (e.g. no operations, tags, or models) still get firstLazyLoadComplete set and the
|
|
26
|
+
* full-viewport placeholder can be hidden. Call from content root on mount.
|
|
27
|
+
*/
|
|
28
|
+
export declare const scheduleInitialLoadComplete: () => void;
|
|
20
29
|
/**
|
|
21
30
|
* Tracks the lazy loading state of an element.
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @param id - The id of the element to track
|
|
25
|
-
* @returns An object with the isReady property
|
|
31
|
+
* Use isReady (or expanded) to decide whether to render the slot or show a placeholder.
|
|
32
|
+
* The element is only added to the queue when it enters the viewport overscan (see Lazy.vue).
|
|
26
33
|
*/
|
|
27
34
|
export declare function useLazyBus(id: string): {
|
|
28
35
|
isReady: import("vue").ComputedRef<boolean>;
|
|
29
36
|
};
|
|
30
37
|
/**
|
|
31
|
-
* Scroll to
|
|
32
|
-
*
|
|
33
|
-
* Will ensure that all parents are expanded and set to priority load before scrolling
|
|
34
|
-
*
|
|
35
|
-
* Similar to scrollToId BUT in the case of a section not being open,
|
|
36
|
-
* it uses the lazyBus to ensure the section is open before scrolling to it
|
|
37
|
-
*
|
|
38
|
-
* Requires handlers to expand and lookup navigation items so that we can
|
|
39
|
-
* traverse the parent structure and load all required items
|
|
38
|
+
* Scroll to a possibly lazy-loaded element. Expands parents and adds target (and
|
|
39
|
+
* parents) to the priority queue, then scrolls after Vue has flushed.
|
|
40
40
|
*/
|
|
41
41
|
export declare const scrollToLazy: (id: string, setExpanded: (id: string, value: boolean) => void, getEntryById: (id: string) => {
|
|
42
42
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazy-bus.d.ts","sourceRoot":"","sources":["../../src/helpers/lazy-bus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lazy-bus.d.ts","sourceRoot":"","sources":["../../src/helpers/lazy-bus.ts"],"names":[],"mappings":"AAuBA,gDAAgD;AAChD,eAAO,MAAM,qBAAqB,qCAAa,CAAA;AAU/C,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,KAAG,MAAM,GAAG,SAA2C,CAAA;AAE1G,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,KAAG,IAKrE,CAAA;AASD,KAAK,SAAS,GAAG,MAAM,IAAI,CAAA;AAE3B;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAO,SAMpC,CAAA;AAED,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,oCAAkD,CAAA;AAsFlF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,IAAI,MAAM,GAAG,SAAS,SAIxD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,IAAI,MAAM,GAAG,SAAS,EAAE,kBAAgB,KAAG,IAY5E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,QAAO,IAM9C,CAAA;AAYD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM;;EAQpC;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,GACvB,IAAI,MAAM,EACV,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,EACjD,cAAc,CAAC,EAAE,EAAE,MAAM,KAAK;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,GAAG,SAAS,SAwD/G,CAAA"}
|
package/dist/helpers/lazy-bus.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { watchDebounced } from "@vueuse/core";
|
|
2
2
|
import { nanoid } from "nanoid";
|
|
3
|
-
import { computed,
|
|
3
|
+
import { computed, reactive, ref, onBeforeUnmount, nextTick } from "vue";
|
|
4
4
|
import { getSchemaParamsFromId } from "./id-routing.js";
|
|
5
5
|
const priorityQueue = reactive(/* @__PURE__ */ new Set());
|
|
6
6
|
const pendingQueue = reactive(/* @__PURE__ */ new Set());
|
|
@@ -10,6 +10,14 @@ const SCROLL_RETRY_MS = 3e3;
|
|
|
10
10
|
const firstLazyLoadComplete = ref(false);
|
|
11
11
|
const intersectionBlockers = reactive(/* @__PURE__ */ new Set());
|
|
12
12
|
const onRenderComplete = /* @__PURE__ */ new Set();
|
|
13
|
+
const lazyPlaceholderHeights = reactive(/* @__PURE__ */ new Map());
|
|
14
|
+
const getLazyPlaceholderHeight = (id) => lazyPlaceholderHeights.get(id);
|
|
15
|
+
const setLazyPlaceholderHeight = (id, height) => {
|
|
16
|
+
if (!Number.isFinite(height) || height <= 0) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
lazyPlaceholderHeights.set(id, Math.round(height));
|
|
20
|
+
};
|
|
13
21
|
const addLazyCompleteCallback = (callback) => {
|
|
14
22
|
if (callback) {
|
|
15
23
|
onRenderComplete.add(callback);
|
|
@@ -25,22 +33,31 @@ const runLazyBus = () => {
|
|
|
25
33
|
if (typeof window === "undefined") {
|
|
26
34
|
return;
|
|
27
35
|
}
|
|
28
|
-
|
|
36
|
+
if (isRunning.value) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
isRunning.value = true;
|
|
29
40
|
const processQueue = async () => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
const priorityIds = [...priorityQueue];
|
|
42
|
+
const pendingIds = [...pendingQueue];
|
|
43
|
+
if (priorityIds.length === 0 && pendingIds.length === 0) {
|
|
44
|
+
onRenderComplete.forEach((fn) => fn());
|
|
45
|
+
onRenderComplete.clear();
|
|
46
|
+
isRunning.value = false;
|
|
47
|
+
firstLazyLoadComplete.value = true;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
for (const id of priorityIds) {
|
|
51
|
+
readyQueue.add(id);
|
|
52
|
+
priorityQueue.delete(id);
|
|
53
|
+
}
|
|
54
|
+
for (const id of pendingIds) {
|
|
55
|
+
readyQueue.add(id);
|
|
56
|
+
pendingQueue.delete(id);
|
|
39
57
|
}
|
|
40
58
|
await nextTick();
|
|
41
59
|
onRenderComplete.forEach((fn) => fn());
|
|
42
60
|
onRenderComplete.clear();
|
|
43
|
-
unblock();
|
|
44
61
|
isRunning.value = false;
|
|
45
62
|
firstLazyLoadComplete.value = true;
|
|
46
63
|
};
|
|
@@ -60,7 +77,7 @@ watchDebounced(
|
|
|
60
77
|
{ debounce: 300, maxWait: 1500 }
|
|
61
78
|
);
|
|
62
79
|
const addToPendingQueue = (id) => {
|
|
63
|
-
if (
|
|
80
|
+
if (id && !readyQueue.has(id) && !priorityQueue.has(id)) {
|
|
64
81
|
pendingQueue.add(id);
|
|
65
82
|
}
|
|
66
83
|
};
|
|
@@ -69,13 +86,33 @@ const addToPriorityQueue = (id) => {
|
|
|
69
86
|
priorityQueue.add(id);
|
|
70
87
|
}
|
|
71
88
|
};
|
|
89
|
+
const requestLazyRender = (id, priority = false) => {
|
|
90
|
+
if (!id || readyQueue.has(id)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (priority) {
|
|
94
|
+
addToPriorityQueue(id);
|
|
95
|
+
} else {
|
|
96
|
+
addToPendingQueue(id);
|
|
97
|
+
}
|
|
98
|
+
if (!isRunning.value) {
|
|
99
|
+
runLazyBus();
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const scheduleInitialLoadComplete = () => {
|
|
103
|
+
if (typeof window === "undefined") {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const delay = 400;
|
|
107
|
+
window.setTimeout(() => runLazyBus(), delay);
|
|
108
|
+
};
|
|
72
109
|
const resetLazyElement = (id) => {
|
|
73
110
|
priorityQueue.delete(id);
|
|
74
111
|
pendingQueue.delete(id);
|
|
75
112
|
readyQueue.delete(id);
|
|
113
|
+
lazyPlaceholderHeights.delete(id);
|
|
76
114
|
};
|
|
77
115
|
function useLazyBus(id) {
|
|
78
|
-
addToPendingQueue(id);
|
|
79
116
|
onBeforeUnmount(() => {
|
|
80
117
|
resetLazyElement(id);
|
|
81
118
|
});
|
|
@@ -93,20 +130,15 @@ const scrollToLazy = (id, setExpanded, getEntryById) => {
|
|
|
93
130
|
addToPriorityQueue(id);
|
|
94
131
|
addToPriorityQueue(rawId);
|
|
95
132
|
if (item?.children) {
|
|
96
|
-
item.children.slice(0, 2).forEach((child) =>
|
|
97
|
-
addToPriorityQueue(child.id);
|
|
98
|
-
});
|
|
133
|
+
item.children.slice(0, 2).forEach((child) => addToPriorityQueue(child.id));
|
|
99
134
|
}
|
|
100
135
|
if (item?.parent) {
|
|
101
136
|
const parent = getEntryById(item.parent.id);
|
|
102
137
|
const elementIdx = parent?.children?.findIndex((child) => child.id === id);
|
|
103
138
|
if (elementIdx !== void 0 && elementIdx >= 0) {
|
|
104
|
-
parent?.children?.slice(elementIdx, elementIdx + 2).forEach((child) =>
|
|
105
|
-
addToPriorityQueue(child.id);
|
|
106
|
-
});
|
|
139
|
+
parent?.children?.slice(elementIdx, elementIdx + 2).forEach((child) => addToPriorityQueue(child.id));
|
|
107
140
|
}
|
|
108
141
|
}
|
|
109
|
-
tryScroll(id, Date.now() + SCROLL_RETRY_MS, unblock, unfreeze);
|
|
110
142
|
setExpanded(rawId, true);
|
|
111
143
|
const addParents = (currentId) => {
|
|
112
144
|
const parent = getEntryById(currentId)?.parent;
|
|
@@ -117,16 +149,17 @@ const scrollToLazy = (id, setExpanded, getEntryById) => {
|
|
|
117
149
|
}
|
|
118
150
|
};
|
|
119
151
|
addParents(rawId);
|
|
152
|
+
void nextTick(() => {
|
|
153
|
+
tryScroll(id, Date.now() + SCROLL_RETRY_MS, unblock, unfreeze);
|
|
154
|
+
});
|
|
120
155
|
};
|
|
121
156
|
const tryScroll = (id, stopTime, onComplete, onFailure) => {
|
|
122
157
|
const element = document.getElementById(id);
|
|
123
158
|
if (element) {
|
|
124
|
-
element.scrollIntoView({
|
|
125
|
-
block: "start"
|
|
126
|
-
});
|
|
159
|
+
element.scrollIntoView({ block: "start" });
|
|
127
160
|
onComplete();
|
|
128
161
|
} else if (Date.now() < stopTime) {
|
|
129
|
-
requestAnimationFrame(() => tryScroll(id, stopTime, onComplete));
|
|
162
|
+
requestAnimationFrame(() => tryScroll(id, stopTime, onComplete, onFailure));
|
|
130
163
|
} else {
|
|
131
164
|
onComplete();
|
|
132
165
|
onFailure?.();
|
|
@@ -137,9 +170,7 @@ const freeze = (id) => {
|
|
|
137
170
|
const runFrame = (stopAfterFrame) => {
|
|
138
171
|
const element = document.getElementById(id);
|
|
139
172
|
if (element) {
|
|
140
|
-
element.scrollIntoView({
|
|
141
|
-
block: "start"
|
|
142
|
-
});
|
|
173
|
+
element.scrollIntoView({ block: "start" });
|
|
143
174
|
}
|
|
144
175
|
if (!stopAfterFrame) {
|
|
145
176
|
requestAnimationFrame(() => runFrame(stop));
|
|
@@ -154,7 +185,11 @@ export {
|
|
|
154
185
|
addToPriorityQueue,
|
|
155
186
|
blockIntersection,
|
|
156
187
|
firstLazyLoadComplete,
|
|
188
|
+
getLazyPlaceholderHeight,
|
|
157
189
|
intersectionEnabled,
|
|
190
|
+
requestLazyRender,
|
|
191
|
+
scheduleInitialLoadComplete,
|
|
158
192
|
scrollToLazy,
|
|
193
|
+
setLazyPlaceholderHeight,
|
|
159
194
|
useLazyBus
|
|
160
195
|
};
|