duckfn-docs-kit 0.1.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/AGENTS.md +689 -0
- package/LICENSE +21 -0
- package/README.md +107 -0
- package/dist/dom.d.ts +69 -0
- package/dist/home/DfkFeatures.d.ts +20 -0
- package/dist/home/DfkHero.d.ts +25 -0
- package/dist/home/DfkNextSteps.d.ts +16 -0
- package/dist/home/styles.d.ts +8 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +2 -0
- package/dist/register-DKLiYs-F.js +2324 -0
- package/dist/register.d.ts +10 -0
- package/dist/remark.d.ts +21 -0
- package/dist/remark.js +15 -0
- package/dist/runtimeConfig-Bokbb8VH.js +106 -0
- package/dist/sql/DfkSql.d.ts +7 -0
- package/dist/sql/PreviewTabs.d.ts +37 -0
- package/dist/sql/client.d.ts +1 -0
- package/dist/sql/client.js +4 -0
- package/dist/sql/editor.d.ts +16 -0
- package/dist/sql/extensions.d.ts +108 -0
- package/dist/sql/extensions.js +198 -0
- package/dist/sql/remark.d.ts +88 -0
- package/dist/sql/remark.js +69 -0
- package/dist/sql/renderers.d.ts +44 -0
- package/dist/sql/runtime.d.ts +105 -0
- package/dist/sql/runtimeConfig.d.ts +80 -0
- package/dist/sql/styles.d.ts +6 -0
- package/dist/toc-toggle/TocToggle.d.ts +46 -0
- package/dist/toc-toggle/TocToggle.js +69 -0
- package/dist/toc-toggle/client.d.ts +1 -0
- package/dist/toc-toggle/client.js +9 -0
- package/dist/toc-toggle/plugin.d.ts +36 -0
- package/dist/toc-toggle/plugin.js +13 -0
- package/dist/types.d.ts +42 -0
- package/package.json +73 -0
- package/src/dom.ts +109 -0
- package/src/home/DfkFeatures.ts +78 -0
- package/src/home/DfkHero.ts +128 -0
- package/src/home/DfkNextSteps.ts +73 -0
- package/src/home/home.css +520 -0
- package/src/home/styles.ts +28 -0
- package/src/index.ts +59 -0
- package/src/kit.css +19 -0
- package/src/register.ts +39 -0
- package/src/remark.ts +60 -0
- package/src/sql/DfkSql.css +226 -0
- package/src/sql/DfkSql.ts +620 -0
- package/src/sql/PreviewTabs.ts +169 -0
- package/src/sql/client.ts +16 -0
- package/src/sql/editor.ts +75 -0
- package/src/sql/extensions.ts +470 -0
- package/src/sql/remark.ts +213 -0
- package/src/sql/renderers.ts +916 -0
- package/src/sql/runtime.ts +348 -0
- package/src/sql/runtimeConfig.ts +249 -0
- package/src/sql/sql.css +397 -0
- package/src/sql/styles.ts +24 -0
- package/src/theme/tokens.css +75 -0
- package/src/toc-toggle/TocToggle.css +69 -0
- package/src/toc-toggle/TocToggle.ts +172 -0
- package/src/toc-toggle/client.ts +20 -0
- package/src/toc-toggle/plugin.ts +54 -0
- package/src/types.ts +47 -0
- package/src/vite-env.d.ts +8 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 shijianjs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# duckfn-docs-kit
|
|
2
|
+
|
|
3
|
+
Shared building blocks for [duckfn](https://github.com/shijianjs/duckfn)-family
|
|
4
|
+
DuckDB extension documentation sites: runnable SQL blocks, extension preloading,
|
|
5
|
+
a TOC collapse control, the home-page web components and the version-placeholder
|
|
6
|
+
remark plugin. Each one is a self-contained entry point that a Docusaurus 3 site
|
|
7
|
+
wires into its own config — the alternative is copying the same glue into every
|
|
8
|
+
extension's docs site.
|
|
9
|
+
|
|
10
|
+
Plain TypeScript over the native DOM: no React and no UI framework of its own.
|
|
11
|
+
The components are retained-mode classes — they build their DOM once, expose
|
|
12
|
+
named domain setters and render into shadow roots, so a site's global CSS and the
|
|
13
|
+
kit's never leak into each other.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install duckfn-docs-kit
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Entry points
|
|
22
|
+
|
|
23
|
+
| Import | Runs in | What it provides |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `duckfn-docs-kit` | browser | Home-page custom elements (`<dfk-hero>`, `<dfk-features>`, `<dfk-next-steps>`, `<dfk-sql>`), `registerDfkElements()` and the value types their setters accept |
|
|
26
|
+
| `duckfn-docs-kit/remark` | Node (build) | `remarkVersionPlaceholder`: replaces `{{DUCKFN_VERSION}}` inside `text` / `inlineCode` / `code` nodes |
|
|
27
|
+
| `duckfn-docs-kit/sql/remark` | Node (build) | `remarkRunnableSql`: turns fenced `sql run` blocks into `<dfk-sql>` elements |
|
|
28
|
+
| `duckfn-docs-kit/sql/extensions` | Node (build) | `dfkExtensions()` Docusaurus plugin: preloads a site's DuckDB extensions before the first block runs |
|
|
29
|
+
| `duckfn-docs-kit/toc-toggle/plugin` | Node (build) | `dfkTocToggle()` Docusaurus plugin: adds the TOC collapse control |
|
|
30
|
+
| `duckfn-docs-kit/toc-toggle/TocToggle` | browser | The TOC collapse class, for a site that drives it itself |
|
|
31
|
+
| `duckfn-docs-kit/src/kit.css` | CSS | Brand tokens plus the styles a shadow boundary cannot host |
|
|
32
|
+
|
|
33
|
+
The two plugins inject their own browser glue (`dfk-*` element registration and
|
|
34
|
+
the TOC toggle) on every page, so a site needs no `clientModules` file of its
|
|
35
|
+
own. `duckfn-docs-kit/sql/client` and `duckfn-docs-kit/toc-toggle/client` are
|
|
36
|
+
that glue — plugins use them, sites should not import them directly.
|
|
37
|
+
|
|
38
|
+
## Wiring it up
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
// docusaurus.config.ts
|
|
42
|
+
import {dfkExtensions} from 'duckfn-docs-kit/sql/extensions';
|
|
43
|
+
import {dfkTocToggle} from 'duckfn-docs-kit/toc-toggle/plugin';
|
|
44
|
+
import {remarkVersionPlaceholder} from 'duckfn-docs-kit/remark';
|
|
45
|
+
import {remarkRunnableSql} from 'duckfn-docs-kit/sql/remark';
|
|
46
|
+
import {DUCKFN_VERSION} from './duckfn-version';
|
|
47
|
+
|
|
48
|
+
export default {
|
|
49
|
+
presets: [
|
|
50
|
+
[
|
|
51
|
+
'classic',
|
|
52
|
+
{
|
|
53
|
+
docs: {
|
|
54
|
+
remarkPlugins: [
|
|
55
|
+
[remarkVersionPlaceholder, {version: DUCKFN_VERSION}],
|
|
56
|
+
remarkRunnableSql,
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
],
|
|
62
|
+
plugins: [
|
|
63
|
+
dfkExtensions({
|
|
64
|
+
allowUnsignedExtensions: true,
|
|
65
|
+
preload: [
|
|
66
|
+
{
|
|
67
|
+
url: 'duckdb-extensions/duckfn.duckdb_extension.wasm',
|
|
68
|
+
release: {
|
|
69
|
+
repository: 'shijianjs/duckfn',
|
|
70
|
+
asset: 'duckfn-wasm_eh.duckdb_extension.wasm',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
}),
|
|
75
|
+
dfkTocToggle(),
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The global CSS is a single import in the site's own stylesheet:
|
|
81
|
+
|
|
82
|
+
```css
|
|
83
|
+
/* src/css/custom.css */
|
|
84
|
+
@import 'duckfn-docs-kit/src/kit.css';
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`kit.css` aggregates the `--duckfn-*` brand tokens and the styles a shadow
|
|
88
|
+
boundary cannot host (the TOC toggle). The `dfk-*` components carry their own
|
|
89
|
+
styles inside the JS bundle, so they need nothing here.
|
|
90
|
+
|
|
91
|
+
## Requirements
|
|
92
|
+
|
|
93
|
+
- Node ≥ 20 and Docusaurus 3.x.
|
|
94
|
+
- `@duckdb/duckdb-wasm` is pinned to an exact version because the WebAssembly
|
|
95
|
+
extensions a site loads have to stay ABI-compatible with the DuckDB build
|
|
96
|
+
inside the wasm bundle. Keep the pin and the extension build in lockstep.
|
|
97
|
+
|
|
98
|
+
## Documentation
|
|
99
|
+
|
|
100
|
+
The user guide lives at <https://shijianjs.github.io/duckfn/docs/docs-kit>. The
|
|
101
|
+
conventions this package is written to — retained-mode components, shadow DOM,
|
|
102
|
+
SSR safety, the SQL rendering contract — are documented in
|
|
103
|
+
[`AGENTS.md`](./AGENTS.md), which ships inside the package.
|
|
104
|
+
|
|
105
|
+
## License
|
|
106
|
+
|
|
107
|
+
MIT
|
package/dist/dom.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM helpers shared by the custom elements.
|
|
3
|
+
*
|
|
4
|
+
* `HTMLElementBase` is the whole reason this module exists: the element classes
|
|
5
|
+
* `extend` it, but Docusaurus imports this package into Node during static
|
|
6
|
+
* prerendering, where the global `HTMLElement` does not exist and evaluating
|
|
7
|
+
* `class X extends HTMLElement` would throw. Falling back to an empty base
|
|
8
|
+
* class keeps module evaluation safe on the server; the real `HTMLElement` is
|
|
9
|
+
* picked up in the browser, where the elements are actually defined and run.
|
|
10
|
+
*/
|
|
11
|
+
export declare const HTMLElementBase: typeof HTMLElement;
|
|
12
|
+
/**
|
|
13
|
+
* The tag's props that hold a value `el()` can assign as-is — `href`, `src`,
|
|
14
|
+
* `alt`, `width`, `hidden`, and so on.
|
|
15
|
+
*
|
|
16
|
+
* Methods and object-valued props are filtered out, so an options bag can never
|
|
17
|
+
* carry `appendChild`, `style`, `dataset` or `classList`. Getter-only props
|
|
18
|
+
* (`origin`, `clientWidth`) do pass the filter; assigning one throws in strict
|
|
19
|
+
* mode, which is loud enough to be caught the first time it runs.
|
|
20
|
+
*/
|
|
21
|
+
type ValueProps<T> = {
|
|
22
|
+
[P in keyof T as T[P] extends Function ? never : T[P] extends object ? never : P]?: T[P];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Options for `el()`: the tag's own props, narrowed to that tag, plus two
|
|
26
|
+
* shorthands and the attribute escape hatch.
|
|
27
|
+
*/
|
|
28
|
+
export type ElOptions<T extends Element> = ValueProps<T> & {
|
|
29
|
+
/** Shorthand for `className`. */
|
|
30
|
+
class?: string;
|
|
31
|
+
/** Shorthand for `textContent`. */
|
|
32
|
+
text?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Attributes that have no matching prop: `aria-*`, `data-*`, and
|
|
35
|
+
* custom-element attributes. Everything else goes through a property, so a
|
|
36
|
+
* boolean or a number keeps its real type instead of being stringified.
|
|
37
|
+
*/
|
|
38
|
+
attrs?: Record<string, string>;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* `document.createElement` with per-tag typed options and an optional `init`
|
|
42
|
+
* callback.
|
|
43
|
+
*
|
|
44
|
+
* The one sanctioned way to build nodes in this package: it returns a live
|
|
45
|
+
* element (held in a class field by the caller), never an HTML string.
|
|
46
|
+
*
|
|
47
|
+
* The options are narrowed to the tag, so a typo, a wrong value type, a method
|
|
48
|
+
* name or an object-valued prop is a compile error:
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* el('img', {class: 'dfk-logo', alt: '', width: 480});
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* `init` describes a subtree in place, for structure that is never referenced
|
|
55
|
+
* again and therefore needs no field:
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* this.root.append(
|
|
59
|
+
* el('span', {class: 'dfk-next-card-body'}, (body) => body.append(this.#title, this.#details)),
|
|
60
|
+
* this.#arrow,
|
|
61
|
+
* );
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* Nodes touched later stay in fields. A field initializer must not read a
|
|
65
|
+
* `#field` declared below it (initializers run in declaration order, so that is
|
|
66
|
+
* a TDZ error) — pass `init` from the constructor, where every field is ready.
|
|
67
|
+
*/
|
|
68
|
+
export declare function el<K extends keyof HTMLElementTagNameMap>(tag: K, options?: ElOptions<HTMLElementTagNameMap[K]> | ((node: HTMLElementTagNameMap[K]) => void), init?: (node: HTMLElementTagNameMap[K]) => void): HTMLElementTagNameMap[K];
|
|
69
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { HTMLElementBase } from '../dom';
|
|
2
|
+
import type { FeatureItem } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* `<dfk-features>` — the "Why duckfn" grid of feature cards. Ported from the
|
|
5
|
+
* home page's `Features()`.
|
|
6
|
+
*
|
|
7
|
+
* Retained-mode: the grid is built once and each card (a {@link DfkFeatureCard})
|
|
8
|
+
* holds its own nodes. `setFeatures()` grows or shrinks the list to the new
|
|
9
|
+
* length and mutates the cards in place — the grid is never cleared and rebuilt.
|
|
10
|
+
*
|
|
11
|
+
* The tree lives in a shadow root (adopting the shared `homeStyles()` sheet);
|
|
12
|
+
* see `DfkHero` for why the theme crosses the boundary through custom
|
|
13
|
+
* properties.
|
|
14
|
+
*/
|
|
15
|
+
export declare class DfkFeatures extends HTMLElementBase {
|
|
16
|
+
#private;
|
|
17
|
+
constructor();
|
|
18
|
+
setSectionTitle(text: string): void;
|
|
19
|
+
setFeatures(items: readonly FeatureItem[]): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { HTMLElementBase } from '../dom';
|
|
2
|
+
import type { HeroAction, HeroBadge, HeroLink } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* `<dfk-hero>` — the landing hero: logo, title, tagline, the two call-to-action
|
|
5
|
+
* buttons and the badge row. Ported from the Docusaurus home page's `Hero()`.
|
|
6
|
+
*
|
|
7
|
+
* Retained-mode: every node is held in a field, the structure is assembled once
|
|
8
|
+
* in the constructor and the `set*` methods only mutate the nodes they own.
|
|
9
|
+
*
|
|
10
|
+
* The tree lives in a shadow root (adopting the shared `homeStyles()` sheet), so
|
|
11
|
+
* the site's global CSS cannot reach it; theme colours cross the boundary
|
|
12
|
+
* through the inherited `--duckfn-*` / `--ifm-*` custom properties.
|
|
13
|
+
*/
|
|
14
|
+
export declare class DfkHero extends HTMLElementBase {
|
|
15
|
+
#private;
|
|
16
|
+
constructor();
|
|
17
|
+
setLogo(src: string): void;
|
|
18
|
+
setTitle(text: string): void;
|
|
19
|
+
setTagline(text: string): void;
|
|
20
|
+
/** The "Get started" button: an internal link, so it stays in the same tab. */
|
|
21
|
+
setPrimaryAction(link: HeroLink): void;
|
|
22
|
+
/** The GitHub button: always external, always carries the glyph. */
|
|
23
|
+
setSecondaryAction(action: HeroAction): void;
|
|
24
|
+
setBadges(badges: readonly HeroBadge[]): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { HTMLElementBase } from '../dom';
|
|
2
|
+
import type { NextStepItem } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* `<dfk-next-steps>` — the "Where to go next" row of link cards. Ported from
|
|
5
|
+
* the home page's `NextSteps()`.
|
|
6
|
+
*
|
|
7
|
+
* Same retained-mode shape as `DfkFeatures`: the grid is built once, each card
|
|
8
|
+
* holds its own nodes, `setSteps()` grows/shrinks the list and mutates in place.
|
|
9
|
+
* The tree lives in a shadow root like the other `dfk-*` elements.
|
|
10
|
+
*/
|
|
11
|
+
export declare class DfkNextSteps extends HTMLElementBase {
|
|
12
|
+
#private;
|
|
13
|
+
constructor();
|
|
14
|
+
setSectionTitle(text: string): void;
|
|
15
|
+
setSteps(items: readonly NextStepItem[]): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one parsed stylesheet shared by every `dfk-*` shadow root.
|
|
3
|
+
*
|
|
4
|
+
* Created lazily: Docusaurus imports this module into Node during
|
|
5
|
+
* prerendering, where `CSSStyleSheet` does not exist — only the browser ever
|
|
6
|
+
* calls this.
|
|
7
|
+
*/
|
|
8
|
+
export declare function homeStyles(): CSSStyleSheet;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Browser entry for duckfn-docs-kit: the home-page custom elements and the
|
|
4
|
+
* value types their `set*` methods accept.
|
|
5
|
+
*
|
|
6
|
+
* The components are retained-mode (build once, then mutate held nodes) and
|
|
7
|
+
* expose named setters such as `setTitle()` / `setBadges()`. They render into
|
|
8
|
+
* shadow roots and inject their own stylesheet, so the consuming site imports
|
|
9
|
+
* only the global CSS the kit cannot host in a shadow (`src/kit.css`: brand
|
|
10
|
+
* tokens + TOC toggle, imported as `duckfn-docs-kit/src/kit.css`). Icons are
|
|
11
|
+
* rendered by the official `<iconify-icon>`
|
|
12
|
+
* web component, which `registerDfkElements()` registers as a side effect, so
|
|
13
|
+
* this package ships no icon data.
|
|
14
|
+
*
|
|
15
|
+
* `TocToggle` and the remark plugin keep their own subpaths
|
|
16
|
+
* (`duckfn-docs-kit/toc-toggle/TocToggle`, `duckfn-docs-kit/remark`) instead of
|
|
17
|
+
* being merged here: a Docusaurus config file must never pull browser code into
|
|
18
|
+
* Node, and a site that only wants the TOC collapse button should not pay for
|
|
19
|
+
* the bundled `iconify-icon`.
|
|
20
|
+
*/
|
|
21
|
+
export { DfkFeatures } from './home/DfkFeatures';
|
|
22
|
+
export { DfkHero } from './home/DfkHero';
|
|
23
|
+
export { DfkNextSteps } from './home/DfkNextSteps';
|
|
24
|
+
export { DfkSql } from './sql/DfkSql';
|
|
25
|
+
export { registerDfkElements } from './register';
|
|
26
|
+
export type { RunnableSqlConfig } from './sql/remark';
|
|
27
|
+
export type { FeatureItem, HeroAction, HeroBadge, HeroLink, NextStepItem, } from './types';
|
|
28
|
+
/**
|
|
29
|
+
* Props accepted by the `dfk-*` tags when they are created from React.
|
|
30
|
+
*
|
|
31
|
+
* The content is *not* passed as a prop — an object prop would never reach the
|
|
32
|
+
* component through hydration (React only reconciles strings onto custom
|
|
33
|
+
* elements). The caller mounts the element and drives it through its setters
|
|
34
|
+
* from a callback ref, so all React needs to know about is `ref`.
|
|
35
|
+
*
|
|
36
|
+
* The alias is exported (rather than written inline) because the emitted `.d.ts`
|
|
37
|
+
* for a module augmentation can only name types that are themselves reachable
|
|
38
|
+
* from the declaration file.
|
|
39
|
+
*/
|
|
40
|
+
export type DfkElementProps = HTMLAttributes<HTMLElement>;
|
|
41
|
+
declare module 'react' {
|
|
42
|
+
namespace JSX {
|
|
43
|
+
interface IntrinsicElements {
|
|
44
|
+
'dfk-hero': DfkElementProps;
|
|
45
|
+
'dfk-features': DfkElementProps;
|
|
46
|
+
'dfk-next-steps': DfkElementProps;
|
|
47
|
+
'dfk-sql': DfkElementProps;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
package/dist/index.js
ADDED