@3sln/deck 0.0.6 → 0.0.8
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/README.md +12 -10
- package/bin/build.js +5 -3
- package/package.json +2 -2
- package/src/deck-demo.js +17 -17
- package/src/highlight.js +2 -0
- package/src/history.js +45 -0
- package/src/main.js +40 -22
- package/src/state.js +34 -8
- package/vite-plugin.js +37 -20
package/README.md
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
A Vite plugin for building scalable, zero-config, Markdown-based component playgrounds and documentation sites.
|
|
1
|
+
# Deck
|
|
4
2
|
|
|
5
3
|
> [!WARNING]
|
|
6
4
|
> This is a work-in-progress project.
|
|
7
5
|
|
|
8
|
-
|
|
6
|
+
Deck is a Vite-based tool for creating scalable, zero-config, Markdown-based component playgrounds and documentation sites.
|
|
7
|
+
|
|
8
|
+
It uses a client-side database to index your documentation, enabling a fast initial load and powerful full-text search, even for very large projects.
|
|
9
|
+
|
|
10
|
+
[deck.webm](https://github.com/user-attachments/assets/cc127ba6-202c-47f0-a982-560e05f7574d)
|
|
11
|
+
|
|
12
|
+
## Documentation & Live Examples
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- **Static Site Generation:** A `deck-build` command generates a fully static, production-ready site from your project files.
|
|
13
|
-
- **`<deck-demo>`:** A powerful custom element for embedding live, stateful, and hot-reloading component demos directly in your documentation.
|
|
14
|
-
- **Reactive UI:** A modern, responsive UI with a powerful search feature and a split-screen layout for easy viewing.
|
|
15
|
-
- **Configurable:** The project title and import maps for dynamic demos can be configured in your project's `package.json`.
|
|
14
|
+
For a complete guide, API reference, and to see Deck in action, you can check out Deck's own
|
|
15
|
+
[card Deck here](https://deck.3sln.com).
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
@@ -24,6 +24,7 @@ A Vite plugin for building scalable, zero-config, Markdown-based component playg
|
|
|
24
24
|
2. **Configure:** In your `package.json`, add a build script and your project's configuration:
|
|
25
25
|
```json
|
|
26
26
|
{
|
|
27
|
+
...
|
|
27
28
|
"scripts": {
|
|
28
29
|
"dev": "vite",
|
|
29
30
|
"build": "deck-build"
|
|
@@ -31,6 +32,7 @@ A Vite plugin for building scalable, zero-config, Markdown-based component playg
|
|
|
31
32
|
"@3sln/deck": {
|
|
32
33
|
"title": "My Awesome Docs"
|
|
33
34
|
}
|
|
35
|
+
...
|
|
34
36
|
}
|
|
35
37
|
```
|
|
36
38
|
|
package/bin/build.js
CHANGED
|
@@ -10,8 +10,7 @@ const require = createRequire(import.meta.url);
|
|
|
10
10
|
|
|
11
11
|
// --- Path Resolution ---
|
|
12
12
|
const userRoot = process.cwd();
|
|
13
|
-
|
|
14
|
-
const assetsDir = path.resolve(outDir, 'assets');
|
|
13
|
+
// outDir is now resolved inside build()
|
|
15
14
|
const deckPluginPath = require.resolve('@3sln/deck/vite-plugin');
|
|
16
15
|
const deckRoot = path.dirname(deckPluginPath);
|
|
17
16
|
|
|
@@ -21,7 +20,10 @@ async function build() {
|
|
|
21
20
|
console.log('Starting Deck build...');
|
|
22
21
|
|
|
23
22
|
const config = await loadDeckConfig(userRoot);
|
|
24
|
-
const buildConfig = config.build;
|
|
23
|
+
const buildConfig = config.build || {};
|
|
24
|
+
|
|
25
|
+
const outDir = path.resolve(userRoot, buildConfig.outDir || 'out');
|
|
26
|
+
const assetsDir = path.resolve(outDir, 'assets');
|
|
25
27
|
|
|
26
28
|
// Clean output directory
|
|
27
29
|
await fs.emptyDir(outDir);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@3sln/deck",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "A Vite plugin for building scalable, zero-config, Markdown-based component playgrounds and documentation sites.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Ray Stubbs",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@3sln/bones": "^0.0.4",
|
|
40
|
-
"@3sln/dodo": "^0.0.
|
|
40
|
+
"@3sln/dodo": "^0.0.5",
|
|
41
41
|
"@3sln/ngin": "^0.0.1",
|
|
42
42
|
"fs-extra": "^11.3.2",
|
|
43
43
|
"glob": "^10.3.10",
|
package/src/deck-demo.js
CHANGED
|
@@ -59,7 +59,7 @@ const propertiesStyle = css`
|
|
|
59
59
|
}
|
|
60
60
|
`;
|
|
61
61
|
|
|
62
|
-
function getEngine(rootNode, key, src) {
|
|
62
|
+
function getEngine(rootNode, key, src, canonicalSrc) {
|
|
63
63
|
if (!rootNodeCaches.has(rootNode)) {
|
|
64
64
|
rootNodeCaches.set(rootNode, new Map());
|
|
65
65
|
}
|
|
@@ -72,7 +72,7 @@ function getEngine(rootNode, key, src) {
|
|
|
72
72
|
return entry.engine;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const {engine, abortController} = createEngine(src);
|
|
75
|
+
const {engine, abortController} = createEngine(src, canonicalSrc);
|
|
76
76
|
const entry = {
|
|
77
77
|
engine,
|
|
78
78
|
refCount: 1,
|
|
@@ -129,7 +129,7 @@ function propertyControl(engine, name) {
|
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
function createEngine(src) {
|
|
132
|
+
function createEngine(src, canonicalSrc) {
|
|
133
133
|
const abortController = new AbortController();
|
|
134
134
|
const sourceCode$ = new ObservableSubject('Loading...');
|
|
135
135
|
|
|
@@ -210,35 +210,35 @@ function createEngine(src) {
|
|
|
210
210
|
engine.dispatch(new UpsertProperty(name, options));
|
|
211
211
|
return engine.query(new PropertyValue(name));
|
|
212
212
|
},
|
|
213
|
-
setActivePanel: name => {
|
|
214
|
-
engine.dispatch(new ActivatePanel(name));
|
|
215
|
-
},
|
|
216
213
|
get signal() {
|
|
217
214
|
return abortController.signal;
|
|
218
215
|
},
|
|
219
216
|
};
|
|
220
217
|
|
|
221
218
|
(async () => {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
219
|
+
const esmSrc = src;
|
|
220
|
+
const textSrc = canonicalSrc || src;
|
|
221
|
+
if (!esmSrc || !textSrc) return;
|
|
225
222
|
|
|
226
223
|
try {
|
|
227
224
|
if (HOT) {
|
|
228
|
-
const
|
|
229
|
-
const
|
|
225
|
+
const esm = await import(/* @vite-ignore */ `/@deck-dev-esm/${encodeURIComponent(esmSrc)}`);
|
|
226
|
+
const txt = await import(/* @vite-ignore */ `/@deck-dev-src/${encodeURIComponent(textSrc)}.js`);
|
|
227
|
+
|
|
228
|
+
const sub = txt.moduleText$.subscribe(text => {
|
|
230
229
|
sourceCode$.next(text);
|
|
231
230
|
});
|
|
232
231
|
abortController.signal.addEventListener('abort', () => {
|
|
233
232
|
sub.unsubscribe();
|
|
234
233
|
});
|
|
235
|
-
|
|
234
|
+
esm.default(driver);
|
|
236
235
|
} else {
|
|
237
|
-
const
|
|
238
|
-
const
|
|
236
|
+
const esmUrl = new URL(esmSrc, location.href);
|
|
237
|
+
const textUrl = new URL(textSrc, location.href);
|
|
238
|
+
const m = await import(/* @vite-ignore */ esmUrl.href);
|
|
239
239
|
m.default(driver);
|
|
240
240
|
|
|
241
|
-
const text = await fetch(
|
|
241
|
+
const text = await fetch(textUrl).then(r => r.text());
|
|
242
242
|
sourceCode$.next(text);
|
|
243
243
|
}
|
|
244
244
|
} catch (err) {
|
|
@@ -736,7 +736,7 @@ class DeckDemo extends HTMLElement {
|
|
|
736
736
|
}
|
|
737
737
|
|
|
738
738
|
this.#id = this.id;
|
|
739
|
-
this.#engine = getEngine(this.getRootNode(), this.id, this.getAttribute('src'));
|
|
739
|
+
this.#engine = getEngine(this.getRootNode(), this.id, this.getAttribute('src'), this.getAttribute('canonical-src'));
|
|
740
740
|
this.#render();
|
|
741
741
|
}
|
|
742
742
|
|
|
@@ -856,4 +856,4 @@ class DeckDemo extends HTMLElement {
|
|
|
856
856
|
}
|
|
857
857
|
}
|
|
858
858
|
|
|
859
|
-
customElements.define('deck-demo', DeckDemo);
|
|
859
|
+
customElements.define('deck-demo', DeckDemo);
|
package/src/highlight.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import hljs from 'highlight.js/lib/core';
|
|
2
2
|
import javascript from 'highlight.js/lib/languages/javascript';
|
|
3
3
|
import xml from 'highlight.js/lib/languages/xml';
|
|
4
|
+
import clojure from 'highlight.js/lib/languages/clojure';
|
|
4
5
|
import css from 'highlight.js/lib/languages/css';
|
|
5
6
|
import githubStyle from 'highlight.js/styles/github.css?inline';
|
|
6
7
|
import githubDarkStyle from 'highlight.js/styles/github-dark.css?inline';
|
|
@@ -9,6 +10,7 @@ import {css as createSheet} from '@3sln/bones/style';
|
|
|
9
10
|
hljs.registerLanguage('javascript', javascript);
|
|
10
11
|
hljs.registerLanguage('xml', xml); // For HTML
|
|
11
12
|
hljs.registerLanguage('css', css);
|
|
13
|
+
hljs.registerLanguage('clojure', clojure);
|
|
12
14
|
|
|
13
15
|
export const stylesheet = createSheet`
|
|
14
16
|
/* Light Theme */
|
package/src/history.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const history = window.history;
|
|
2
|
+
|
|
3
|
+
// Function to get the current query parameters as an object
|
|
4
|
+
export function getQueryParams() {
|
|
5
|
+
const params = new URLSearchParams(window.location.search);
|
|
6
|
+
return {
|
|
7
|
+
q: params.get('q') ?? '',
|
|
8
|
+
c: params.get('c') ?? null,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Function to update the URL with new state
|
|
13
|
+
// Uses replaceState to avoid polluting the history for rapid changes
|
|
14
|
+
export function replaceState(params) {
|
|
15
|
+
const url = new URL(window.location);
|
|
16
|
+
if (params.hasOwnProperty('q')) {
|
|
17
|
+
if (params.q) url.searchParams.set('q', params.q);
|
|
18
|
+
else url.searchParams.delete('q');
|
|
19
|
+
}
|
|
20
|
+
if (params.hasOwnProperty('c')) {
|
|
21
|
+
if (params.c) url.searchParams.set('c', params.c);
|
|
22
|
+
else url.searchParams.delete('c');
|
|
23
|
+
}
|
|
24
|
+
history.replaceState({}, '', url.toString());
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Function to push a new state to the history
|
|
28
|
+
// Use this for significant changes, like selecting a new card
|
|
29
|
+
export function pushState(params) {
|
|
30
|
+
const url = new URL(window.location);
|
|
31
|
+
if (params.hasOwnProperty('q')) {
|
|
32
|
+
if (params.q) url.searchParams.set('q', params.q);
|
|
33
|
+
else url.searchParams.delete('q');
|
|
34
|
+
}
|
|
35
|
+
if (params.hasOwnProperty('c')) {
|
|
36
|
+
if (params.c) url.searchParams.set('c', params.c);
|
|
37
|
+
else url.searchParams.delete('c');
|
|
38
|
+
}
|
|
39
|
+
history.pushState({}, '', url.toString());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Wrapper for popstate event
|
|
43
|
+
export function onPopState(callback) {
|
|
44
|
+
window.addEventListener('popstate', callback);
|
|
45
|
+
}
|
package/src/main.js
CHANGED
|
@@ -5,6 +5,7 @@ import {Engine, Provider} from '@3sln/ngin';
|
|
|
5
5
|
import * as db from './db.js';
|
|
6
6
|
import { ThrottledFetcher } from './fetcher.js';
|
|
7
7
|
import {highlight, stylesheet as highlightStylesheet} from './highlight.js';
|
|
8
|
+
import * as history from './history.js';
|
|
8
9
|
import {
|
|
9
10
|
uiStateProvider,
|
|
10
11
|
FilteredCards,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
RemoveCard,
|
|
17
18
|
PruneCards,
|
|
18
19
|
SetPinnedCards,
|
|
20
|
+
SearchQuery
|
|
19
21
|
} from './state.js';
|
|
20
22
|
import './deck-demo.js';
|
|
21
23
|
|
|
@@ -43,27 +45,32 @@ const closeIcon = () =>
|
|
|
43
45
|
);
|
|
44
46
|
|
|
45
47
|
const searchBar = alias(engine => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
48
|
+
const query$ = engine.query(new SearchQuery());
|
|
49
|
+
|
|
50
|
+
return watch(query$, query =>
|
|
51
|
+
div(
|
|
52
|
+
{className: 'search-bar'},
|
|
53
|
+
input({
|
|
54
|
+
type: 'search',
|
|
55
|
+
placeholder: 'Search cards...',
|
|
56
|
+
value: query,
|
|
57
|
+
$styling: {
|
|
58
|
+
width: '100%',
|
|
59
|
+
padding: '0.75em 1em',
|
|
60
|
+
'font-size': '1.1em',
|
|
61
|
+
border: '1px solid var(--input-border)',
|
|
62
|
+
'background-color': 'var(--input-bg)',
|
|
63
|
+
color: 'var(--text-color)',
|
|
64
|
+
'border-radius': '2em',
|
|
65
|
+
outline: 'none',
|
|
66
|
+
transition: 'box-shadow 0.2s',
|
|
67
|
+
},
|
|
68
|
+
}).on({
|
|
69
|
+
focus: e => (e.target.style.boxShadow = '0 0 5px rgba(81, 203, 238, 1)'),
|
|
70
|
+
blur: e => (e.target.style.boxShadow = 'none'),
|
|
71
|
+
input: e => engine.dispatch(new SetSearchQuery(e.target.value)),
|
|
72
|
+
}),
|
|
73
|
+
),
|
|
67
74
|
);
|
|
68
75
|
});
|
|
69
76
|
|
|
@@ -301,6 +308,7 @@ export async function renderDeck({target, initialCardsData, pinnedCardPaths}) {
|
|
|
301
308
|
providers: {
|
|
302
309
|
state: uiStateProvider(),
|
|
303
310
|
fetcher: Provider.fromSingleton(new ThrottledFetcher()),
|
|
311
|
+
history: Provider.fromSingleton(history),
|
|
304
312
|
},
|
|
305
313
|
});
|
|
306
314
|
|
|
@@ -311,6 +319,16 @@ export async function renderDeck({target, initialCardsData, pinnedCardPaths}) {
|
|
|
311
319
|
});
|
|
312
320
|
engine.dispatch(new PruneCards(initialCardsData.map(c => c.path)));
|
|
313
321
|
|
|
322
|
+
const syncNav = () => {
|
|
323
|
+
const {q, c} = history.getQueryParams();
|
|
324
|
+
console.log('q', q);
|
|
325
|
+
engine.dispatch(new SelectCard(c));
|
|
326
|
+
engine.dispatch(new SetSearchQuery(q));
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
history.onPopState(syncNav);
|
|
330
|
+
syncNav();
|
|
331
|
+
|
|
314
332
|
// Handle HMR
|
|
315
333
|
if (import.meta.hot) {
|
|
316
334
|
import.meta.hot.on('deck:card-changed', ({path}) => {
|
|
@@ -323,4 +341,4 @@ export async function renderDeck({target, initialCardsData, pinnedCardPaths}) {
|
|
|
323
341
|
}
|
|
324
342
|
|
|
325
343
|
reconcile(target, [app(engine)]);
|
|
326
|
-
}
|
|
344
|
+
}
|
package/src/state.js
CHANGED
|
@@ -186,31 +186,57 @@ export class RemoveCard extends Action {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
export class SetSearchQuery extends Action {
|
|
189
|
-
static deps = ['state'];
|
|
189
|
+
static deps = ['state', 'history'];
|
|
190
190
|
constructor(query) {
|
|
191
191
|
super();
|
|
192
192
|
this.query = query;
|
|
193
193
|
}
|
|
194
|
-
execute({state}) {
|
|
194
|
+
execute({state, history}) {
|
|
195
|
+
if (this.query !== state.state$.value.query) {
|
|
196
|
+
history.replaceState({q: this.query});
|
|
197
|
+
}
|
|
195
198
|
state.update(s => ({...s, query: this.query}));
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
201
|
|
|
199
202
|
export class SelectCard extends Action {
|
|
200
|
-
static deps = ['state'];
|
|
203
|
+
static deps = ['state', 'history'];
|
|
201
204
|
constructor(cardPath) {
|
|
202
205
|
super();
|
|
203
206
|
this.cardPath = cardPath;
|
|
204
207
|
}
|
|
205
|
-
async execute({state}) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
+
async execute({state, history}) {
|
|
209
|
+
if (!this.cardPath) {
|
|
210
|
+
if (state.state$.value.selectedCardPath !== null) {
|
|
211
|
+
history.pushState({c: null});
|
|
212
|
+
state.update(s => ({...s, selectedCardPath: null}));
|
|
213
|
+
}
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const card = await db.getCard(this.cardPath);
|
|
218
|
+
|
|
219
|
+
if (card) {
|
|
220
|
+
if (this.cardPath !== state.state$.value.selectedCardPath) {
|
|
221
|
+
history.pushState({c: this.cardPath});
|
|
222
|
+
}
|
|
223
|
+
await db.touchCard(this.cardPath);
|
|
224
|
+
state.update(s => ({...s, selectedCardPath: this.cardPath}));
|
|
225
|
+
} else {
|
|
226
|
+
if (state.state$.value.selectedCardPath !== null) {
|
|
227
|
+
history.pushState({c: null});
|
|
228
|
+
}
|
|
229
|
+
state.update(s => ({...s, selectedCardPath: null}));
|
|
230
|
+
}
|
|
208
231
|
}
|
|
209
232
|
}
|
|
210
233
|
|
|
211
234
|
export class ClearSelection extends Action {
|
|
212
|
-
static deps = ['state'];
|
|
213
|
-
execute({state}) {
|
|
235
|
+
static deps = ['state', 'history'];
|
|
236
|
+
execute({state, history}) {
|
|
237
|
+
if (state.state$.value.selectedCardPath !== null) {
|
|
238
|
+
history.pushState({c: null});
|
|
239
|
+
}
|
|
214
240
|
state.update(s => ({...s, selectedCardPath: null}));
|
|
215
241
|
}
|
|
216
242
|
}
|
package/vite-plugin.js
CHANGED
|
@@ -9,7 +9,7 @@ export default function deckPlugin() {
|
|
|
9
9
|
name: 'vite-plugin-deck',
|
|
10
10
|
|
|
11
11
|
resolveId(id) {
|
|
12
|
-
if (id.startsWith('/@deck-dev-
|
|
12
|
+
if (id.startsWith('/@deck-dev-esm/') || id.startsWith('/@deck-dev-src/')) {
|
|
13
13
|
return id;
|
|
14
14
|
}
|
|
15
15
|
return null;
|
|
@@ -29,12 +29,10 @@ export default function deckPlugin() {
|
|
|
29
29
|
},
|
|
30
30
|
|
|
31
31
|
load(id) {
|
|
32
|
-
if (id.startsWith('/@deck-dev-
|
|
33
|
-
const realPath = decodeURIComponent(id.slice('/@deck-dev-
|
|
34
|
-
const rawPath = realPath + '?raw';
|
|
32
|
+
if (id.startsWith('/@deck-dev-esm/')) {
|
|
33
|
+
const realPath = decodeURIComponent(id.slice('/@deck-dev-esm/'.length));
|
|
35
34
|
return `
|
|
36
35
|
import realDefault from '${realPath}';
|
|
37
|
-
import moduleText from '${rawPath}';
|
|
38
36
|
|
|
39
37
|
let lastArgs;
|
|
40
38
|
let abortController = new AbortController();
|
|
@@ -43,6 +41,36 @@ export default function deckPlugin() {
|
|
|
43
41
|
lastArgs = import.meta.hot.data.lastArgs;
|
|
44
42
|
}
|
|
45
43
|
|
|
44
|
+
export default (...args) => {
|
|
45
|
+
lastArgs = args;
|
|
46
|
+
const thisContext = { signal: abortController.signal };
|
|
47
|
+
realDefault.call(thisContext, ...args);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (import.meta.hot) {
|
|
51
|
+
import.meta.hot.dispose(data => {
|
|
52
|
+
data.lastArgs = lastArgs;
|
|
53
|
+
abortController.abort();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
import.meta.hot.accept(newModule => {
|
|
57
|
+
if (newModule && newModule.default && lastArgs) {
|
|
58
|
+
newModule.default(...lastArgs);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (id.startsWith('/@deck-dev-src/')) {
|
|
66
|
+
let realPath = decodeURIComponent(id.slice('/@deck-dev-src/'.length));
|
|
67
|
+
if (realPath.endsWith('.js')) {
|
|
68
|
+
realPath = realPath.slice(0, -3);
|
|
69
|
+
}
|
|
70
|
+
const rawPath = realPath + '?raw';
|
|
71
|
+
return `
|
|
72
|
+
import moduleText from '${rawPath}';
|
|
73
|
+
|
|
46
74
|
const textObservers = import.meta.hot?.data.textObservers ?? [];
|
|
47
75
|
export const moduleText$ = {
|
|
48
76
|
subscribe: observer => {
|
|
@@ -58,24 +86,12 @@ export default function deckPlugin() {
|
|
|
58
86
|
}
|
|
59
87
|
};
|
|
60
88
|
|
|
61
|
-
export default (...args) => {
|
|
62
|
-
lastArgs = args;
|
|
63
|
-
const thisContext = { signal: abortController.signal };
|
|
64
|
-
realDefault.call(thisContext, ...args);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
89
|
if (import.meta.hot) {
|
|
90
|
+
import.meta.hot.accept();
|
|
68
91
|
import.meta.hot.dispose(data => {
|
|
69
|
-
data.lastArgs = lastArgs;
|
|
70
92
|
data.textObservers = textObservers;
|
|
71
|
-
abortController.abort();
|
|
72
93
|
});
|
|
73
94
|
|
|
74
|
-
import.meta.hot.accept(newModule => {
|
|
75
|
-
if (newModule && newModule.default && lastArgs) {
|
|
76
|
-
newModule.default(...lastArgs);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
95
|
import.meta.hot.on('deck-raw-update', ({urls, text}) => {
|
|
80
96
|
if (!urls.includes('${rawPath}')) {
|
|
81
97
|
return;
|
|
@@ -88,6 +104,7 @@ export default function deckPlugin() {
|
|
|
88
104
|
}
|
|
89
105
|
`;
|
|
90
106
|
}
|
|
107
|
+
|
|
91
108
|
return null;
|
|
92
109
|
},
|
|
93
110
|
|
|
@@ -106,7 +123,7 @@ export default function deckPlugin() {
|
|
|
106
123
|
server.watcher.on('all', (eventName, eventPath) => {
|
|
107
124
|
const projPath = path.relative(resolvedConfig.root, eventPath);
|
|
108
125
|
const webPath = '/' + projPath.replace(/\\/g, '/');
|
|
109
|
-
const files =
|
|
126
|
+
const files = getCardFiles(resolvedConfig.root, devConfig).map(p => `/${p}`);
|
|
110
127
|
if (!files.includes(webPath)) return;
|
|
111
128
|
|
|
112
129
|
switch (eventName) {
|
|
@@ -121,7 +138,7 @@ export default function deckPlugin() {
|
|
|
121
138
|
});
|
|
122
139
|
|
|
123
140
|
server.middlewares.use(async (req, res, next) => {
|
|
124
|
-
if (req.url.
|
|
141
|
+
if (new URL(req.url, "https://localhost").pathname === '/') {
|
|
125
142
|
const cardPaths = getCardFiles(resolvedConfig.root, devConfig).map(p => `/${p}`);
|
|
126
143
|
const initialCardsData = await Promise.all(cardPaths.map(async (p) => {
|
|
127
144
|
const content = await fs.readFile(path.join(resolvedConfig.root, p), 'utf-8');
|