@stacksjs/stx 0.2.155 → 0.2.156
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/a11y.d.ts +87 -46
- package/dist/animation.d.ts +96 -42
- package/dist/appearance-bootstrap.d.ts +49 -15
- package/dist/asset-roots.d.ts +32 -0
- package/dist/asset-roots.js +7 -0
- package/dist/assets.d.ts +9 -7
- package/dist/async-components.d.ts +78 -56
- package/dist/auth.d.ts +3 -0
- package/dist/build-externalize.d.ts +40 -0
- package/dist/build-externalize.js +63 -0
- package/dist/build-id.d.ts +22 -22
- package/dist/build-message.d.ts +73 -2
- package/dist/build-message.js +47 -8
- package/dist/builtins/attrs.d.ts +14 -0
- package/dist/builtins/drawer.d.ts +22 -0
- package/dist/builtins/icon.d.ts +16 -2
- package/dist/builtins/index.d.ts +5 -15
- package/dist/builtins/modal.d.ts +24 -0
- package/dist/builtins/safe-image.d.ts +42 -0
- package/dist/builtins/stx-image.d.ts +27 -0
- package/dist/builtins/stx-link.d.ts +9 -0
- package/dist/builtins/stx-loading-indicator.d.ts +11 -0
- package/dist/builtins/suspense.d.ts +28 -0
- package/dist/builtins/toast.d.ts +17 -0
- package/dist/builtins/transition-group.d.ts +25 -0
- package/dist/caching.d.ts +12 -15
- package/dist/cli.js +1798 -908
- package/dist/client/directive.d.ts +7 -0
- package/dist/client/index.d.ts +0 -1
- package/dist/client-script-bundler.d.ts +63 -5
- package/dist/client-script-bundler.js +30 -2
- package/dist/client-script.d.ts +102 -47
- package/dist/client-script.js +15 -3
- package/dist/codemod.d.ts +56 -0
- package/dist/codemod.js +192 -0
- package/dist/color-mode-boot.d.ts +83 -65
- package/dist/component-client-factories.d.ts +1 -6
- package/dist/component-processing.d.ts +58 -49
- package/dist/component-processing.js +1 -1
- package/dist/component-registry.d.ts +94 -31
- package/dist/component-renderer.d.ts +18 -0
- package/dist/composable-loader.d.ts +24 -0
- package/dist/composable-loader.js +12 -9
- package/dist/composables/index.d.ts +7 -0
- package/dist/composables/index.js +1 -0
- package/dist/composables/use-fetch.js +30 -2
- package/dist/composables/use-form.d.ts +91 -0
- package/dist/composables/use-form.js +112 -0
- package/dist/composables.d.ts +64 -60
- package/dist/computed.d.ts +86 -92
- package/dist/conditionals.d.ts +24 -8
- package/dist/conditionals.js +16 -0
- package/dist/config.d.ts +34 -21
- package/dist/config.js +35 -14
- package/dist/craft.js +1476 -768
- package/dist/crosswind-config.d.ts +58 -0
- package/dist/crosswind-config.js +40 -0
- package/dist/csp.d.ts +107 -41
- package/dist/defer.d.ts +24 -0
- package/dist/dev-server/crosswind.d.ts +35 -26
- package/dist/dev-server/crosswind.js +2 -18
- package/dist/dev-server/serve-app.js +4 -3
- package/dist/dev-server/terminal-colors.d.ts +32 -32
- package/dist/directive-api.d.ts +86 -43
- package/dist/document-shell.d.ts +54 -41
- package/dist/dynamic-components.d.ts +9 -0
- package/dist/error-boundaries.d.ts +47 -41
- package/dist/error-handling.d.ts +1 -1
- package/dist/errors/codes.d.ts +51 -43
- package/dist/errors/formatter.d.ts +58 -38
- package/dist/errors/index.d.ts +5 -61
- package/dist/errors/logger.d.ts +114 -40
- package/dist/errors/sanitizer.d.ts +53 -23
- package/dist/errors/types.d.ts +44 -31
- package/dist/events.d.ts +86 -25
- package/dist/expressions.d.ts +50 -42
- package/dist/forms-validation.d.ts +138 -123
- package/dist/forms-validation.js +1 -90
- package/dist/forms.d.ts +120 -66
- package/dist/forms.js +31 -11
- package/dist/fragment-container.d.ts +57 -0
- package/dist/fragment-container.js +109 -0
- package/dist/framework-composables.d.ts +32 -0
- package/dist/head.d.ts +156 -114
- package/dist/heatmap.d.ts +152 -72
- package/dist/html-masking.d.ts +40 -34
- package/dist/hydration-runtime.d.ts +20 -24
- package/dist/i18n.d.ts +93 -32
- package/dist/image-optimization/auto-sibling.d.ts +32 -4
- package/dist/includes.d.ts +69 -7
- package/dist/index.d.ts +66 -0
- package/dist/index.js +23 -0
- package/dist/internal-markdown.d.ts +12 -8
- package/dist/island-chunking.d.ts +30 -13
- package/dist/keep-alive.d.ts +72 -52
- package/dist/layout-types.d.ts +45 -0
- package/dist/layout-types.js +56 -0
- package/dist/lazy-module.d.ts +10 -0
- package/dist/loops.d.ts +66 -0
- package/dist/loops.js +47 -6
- package/dist/markdown.d.ts +0 -1
- package/dist/media/image/component.d.ts +25 -9
- package/dist/media/image/directive.d.ts +15 -1
- package/dist/media/image/placeholder.d.ts +20 -9
- package/dist/media/image/processor/cache.d.ts +40 -18
- package/dist/media/image/processor/index.d.ts +1 -10
- package/dist/media/image/processor/optimizer.d.ts +12 -1
- package/dist/media/image/processor/responsive.d.ts +16 -6
- package/dist/media/image/srcset.d.ts +47 -50
- package/dist/media/shared/cache.d.ts +51 -31
- package/dist/media/shared/hash.d.ts +7 -0
- package/dist/media/types.d.ts +1235 -754
- package/dist/media/video/directive.d.ts +15 -1
- package/dist/media/video/index.d.ts +39 -17
- package/dist/media/video/processor/cache.d.ts +42 -19
- package/dist/media/video/processor/index.d.ts +1 -18
- package/dist/media/video/processor/streaming.d.ts +17 -10
- package/dist/media/video/processor/thumbnail.d.ts +21 -15
- package/dist/media/video/processor/transcoder.d.ts +11 -1
- package/dist/method-spoofing.d.ts +7 -0
- package/dist/middleware.d.ts +60 -0
- package/dist/owned-routes.d.ts +42 -0
- package/dist/owned-routes.js +26 -0
- package/dist/page-meta.d.ts +38 -0
- package/dist/page-meta.js +16 -0
- package/dist/parser/directive-parser.d.ts +57 -45
- package/dist/parser/expression-parser.d.ts +33 -35
- package/dist/parser/index.d.ts +4 -39
- package/dist/parser/tokenizer.d.ts +61 -49
- package/dist/partial-hydration.d.ts +82 -50
- package/dist/performance-utils.d.ts +217 -124
- package/dist/placeholder.d.ts +18 -9
- package/dist/plugin-system.d.ts +264 -115
- package/dist/process.d.ts +11 -6
- package/dist/process.js +21 -4
- package/dist/production-builder.js +7 -0
- package/dist/prop-sentinels.d.ts +11 -11
- package/dist/public-env.d.ts +14 -0
- package/dist/pwa/directives.d.ts +12 -3
- package/dist/pwa/inject.d.ts +10 -0
- package/dist/pwa/precache.d.ts +22 -16
- package/dist/pwa/service-worker.d.ts +12 -0
- package/dist/pwa.js +1318 -610
- package/dist/reactive-bindings.d.ts +34 -11
- package/dist/reactive.d.ts +58 -30
- package/dist/reactive.js +56 -31
- package/dist/render.js +1 -0
- package/dist/route-middleware.d.ts +2 -35
- package/dist/route-types.d.ts +134 -0
- package/dist/route-types.js +24 -0
- package/dist/router.d.ts +5 -7
- package/dist/routes.d.ts +1 -3
- package/dist/runtime-globals.d.ts +147 -24
- package/dist/runtime-globals.js +16 -1
- package/dist/runtime-injection.d.ts +8 -0
- package/dist/runtime-injection.js +33 -24
- package/dist/script-emit.d.ts +30 -0
- package/dist/script-json.d.ts +36 -0
- package/dist/script-json.js +6 -0
- package/dist/script-validation.d.ts +21 -4
- package/dist/seo.d.ts +118 -47
- package/dist/server-bindings.d.ts +21 -0
- package/dist/sfc-template.d.ts +8 -8
- package/dist/signal-processing.d.ts +35 -15
- package/dist/signals-api.d.ts +117 -58
- package/dist/signals-api.js +7 -4
- package/dist/signals.d.ts +24 -17
- package/dist/signals.js +765 -60
- package/dist/site-builder/build.js +8 -0
- package/dist/site-url.d.ts +46 -0
- package/dist/site-url.js +70 -0
- package/dist/slots.d.ts +86 -20
- package/dist/source-signature.d.ts +45 -0
- package/dist/source-signature.js +20 -0
- package/dist/ssg.d.ts +285 -142
- package/dist/ssg.js +1268 -556
- package/dist/state-dir.d.ts +4 -4
- package/dist/state-management.d.ts +0 -12
- package/dist/state-management.js +8 -25
- package/dist/store-imports.d.ts +23 -0
- package/dist/store-imports.js +3 -0
- package/dist/store-loader.d.ts +10 -0
- package/dist/store-loader.js +10 -9
- package/dist/story/analytics.d.ts +138 -60
- package/dist/story/bookmarks.d.ts +87 -34
- package/dist/story/cli.d.ts +123 -69
- package/dist/story/collect/scanner.d.ts +4 -0
- package/dist/story/collect/tree.d.ts +8 -1
- package/dist/story/commands/build.d.ts +11 -6
- package/dist/story/commands/dev.d.ts +15 -8
- package/dist/story/commands/preview.d.ts +13 -7
- package/dist/story/config-watcher.d.ts +20 -13
- package/dist/story/config.d.ts +11 -8
- package/dist/story/context.d.ts +14 -8
- package/dist/story/hmr.d.ts +24 -26
- package/dist/story/hot-swap.d.ts +34 -23
- package/dist/story/keyboard-shortcuts.d.ts +23 -18
- package/dist/story/output.d.ts +46 -44
- package/dist/story/performance.d.ts +107 -45
- package/dist/story/presets.d.ts +107 -41
- package/dist/story/renderer.d.ts +41 -27
- package/dist/story/search.d.ts +23 -12
- package/dist/story/server.d.ts +21 -11
- package/dist/story/setup.d.ts +23 -15
- package/dist/story/testing.d.ts +65 -40
- package/dist/story/types.d.ts +262 -160
- package/dist/streaming.d.ts +119 -57
- package/dist/stx-virtual-ts.d.ts +165 -0
- package/dist/stx-virtual-ts.js +372 -0
- package/dist/stx.d.ts +78 -1
- package/dist/style-scoping.d.ts +17 -4
- package/dist/suspense.d.ts +67 -52
- package/dist/teleport.d.ts +22 -0
- package/dist/template-tag-balance.d.ts +22 -6
- package/dist/transitions.d.ts +66 -55
- package/dist/typecheck.d.ts +77 -0
- package/dist/typecheck.js +156 -0
- package/dist/types/component-types.d.ts +187 -122
- package/dist/types/config-types.d.ts +758 -297
- package/dist/types/context-types.d.ts +46 -24
- package/dist/types/csp-types.d.ts +70 -66
- package/dist/types/directive-types.d.ts +211 -155
- package/dist/types/index.d.ts +6 -109
- package/dist/types/pwa-types.d.ts +273 -148
- package/dist/types.d.ts +0 -1
- package/dist/typescript-templates.d.ts +11 -0
- package/dist/unresolved-identifiers.d.ts +24 -22
- package/dist/unresolved-identifiers.js +2 -0
- package/dist/utils.d.ts +24 -21
- package/dist/validator.d.ts +28 -26
- package/dist/variable-extractor.d.ts +48 -13
- package/dist/variable-extractor.js +27 -4
- package/dist/view-composers.d.ts +80 -81
- package/dist/virtual-scrolling.d.ts +101 -81
- package/dist/vue-template.d.ts +23 -0
- package/dist/web-components/css-scoping.d.ts +21 -11
- package/dist/web-components.d.ts +81 -58
- package/dist/x-element.d.ts +0 -1
- package/package.json +5 -5
- package/stx.d.ts +78 -1
package/dist/index.d.ts
CHANGED
|
@@ -44,6 +44,38 @@ export {
|
|
|
44
44
|
useStorage,
|
|
45
45
|
type UseStorageOptions,
|
|
46
46
|
} from './composables/use-storage';
|
|
47
|
+
// View composers were unreachable: `runComposers` is wired into the render
|
|
48
|
+
// pipeline (process.ts:1206) and runs on every render, but the two functions that
|
|
49
|
+
// PUT anything in the registry were never exported, so the registry was always
|
|
50
|
+
// empty and the whole layer was dead weight. The module's own docblock tells you
|
|
51
|
+
// to `import { composer } from 'stx'`, which threw. The existing test suite
|
|
52
|
+
// imported from './view-composers' directly, so nothing exercised the public
|
|
53
|
+
// surface and the gap stayed invisible. See #1860.
|
|
54
|
+
export {
|
|
55
|
+
clearComposers,
|
|
56
|
+
composer,
|
|
57
|
+
composerPattern,
|
|
58
|
+
runComposers,
|
|
59
|
+
type ViewComposerCallback,
|
|
60
|
+
} from './view-composers';
|
|
61
|
+
// useForm and the `v` validator builder shipped unreachable: the module's
|
|
62
|
+
// docblock says `import { useForm, v } from 'stx'` (forms-validation.ts:9),
|
|
63
|
+
// and that import threw. process.ts reached the module lazily for directive
|
|
64
|
+
// processing only, so the form primitive itself had no way in. See #1856.
|
|
65
|
+
//
|
|
66
|
+
// `defineForm` is the deprecated pre-#1843 spelling, exported alongside so an
|
|
67
|
+
// app does not have to rename in the same release it upgrades in.
|
|
68
|
+
export {
|
|
69
|
+
defineForm,
|
|
70
|
+
useForm,
|
|
71
|
+
v,
|
|
72
|
+
Validator,
|
|
73
|
+
type ValidatorFn,
|
|
74
|
+
type AsyncValidatorFn,
|
|
75
|
+
type ValidatorRule,
|
|
76
|
+
type FieldState,
|
|
77
|
+
type FormState,
|
|
78
|
+
} from './forms-validation';
|
|
47
79
|
export { formatSize, getTotalSize } from './deploy/index';
|
|
48
80
|
export { type ImageRenderResult, type ImageVariant, type ProcessedImage, clearImageCache, getFallbackVariant, getMimeType, groupVariantsByFormat, optimizeImage, processImage } from './image-optimization/index';
|
|
49
81
|
export { type AnalysisResult } from './analyzer';
|
|
@@ -96,6 +128,16 @@ export * from './defer';
|
|
|
96
128
|
export * from './deploy/index';
|
|
97
129
|
export * from './dev-server';
|
|
98
130
|
export * from './document-shell';
|
|
131
|
+
export * from './fragment-container';
|
|
132
|
+
// DevTools entry points. Exported selectively rather than with a wildcard:
|
|
133
|
+
// devtools.ts also exports registerStore, which would collide with
|
|
134
|
+
// state-management's function of the same name. Their own docblock says
|
|
135
|
+
// `import { enableDevTools } from 'stx'`, and that import threw — so devtools
|
|
136
|
+
// could not be turned on from the package entry at all. See #1873.
|
|
137
|
+
export { disableDevTools, enableDevTools } from './devtools';
|
|
138
|
+
// composables.ts:161 documents `import { onUpdate } from 'stx'`; it was
|
|
139
|
+
// reachable only through the stx/composables subpath.
|
|
140
|
+
export { onUpdate } from './composables';
|
|
99
141
|
export * from './directive-api';
|
|
100
142
|
export * from './docs';
|
|
101
143
|
export * from './edge-runtime';
|
|
@@ -137,6 +179,10 @@ export * from './suspense';
|
|
|
137
179
|
export * from './teleport';
|
|
138
180
|
export * from './transitions';
|
|
139
181
|
export * from './type-checker';
|
|
182
|
+
// Type-checking the TypeScript inside .stx script blocks, and the CLI behind
|
|
183
|
+
// `stx typecheck` (#1852). Distinct from ./type-checker, which is a bespoke
|
|
184
|
+
// checker for template EXPRESSIONS.
|
|
185
|
+
export * from './typecheck';
|
|
140
186
|
export * from './web-components';
|
|
141
187
|
export * from './virtual-scrolling';
|
|
142
188
|
export * from './partial-hydration';
|
|
@@ -178,6 +224,26 @@ export { definePlugin, pluginManager } from './plugin-system';
|
|
|
178
224
|
// These modules are exported first to establish their types
|
|
179
225
|
export * from './render';
|
|
180
226
|
export { extractClassNames, generateCrosswindCSS, getCrosswindServeAsset, injectCrosswindCSS } from './dev-server/crosswind';
|
|
227
|
+
// One crosswind merge shared by every render path (#1867)
|
|
228
|
+
export { deepMergeThemes, mergeCrosswindConfig, type MergedCrosswindConfig } from './crosswind-config';
|
|
229
|
+
// Dev-mode invalidation for the store/composable bundles (#1877)
|
|
230
|
+
export { clearStoreCache, getStoreScript } from './store-loader';
|
|
231
|
+
export { clearComposableCache } from './composable-loader';
|
|
232
|
+
// Generated union of layouts on disk (#1879)
|
|
233
|
+
export { discoverLayoutNames, generateLayoutTypes, LAYOUT_TYPES_FILE, renderLayoutTypes } from './layout-types';
|
|
234
|
+
// Typed route paths (#1887). Without this export the generated augmentation is
|
|
235
|
+
// dangling again, for exactly the reason `stx/routes` was.
|
|
236
|
+
export {
|
|
237
|
+
$path,
|
|
238
|
+
type CheckHref,
|
|
239
|
+
type KnownRoutes,
|
|
240
|
+
type RouteHref,
|
|
241
|
+
type RouteParams,
|
|
242
|
+
type RoutePath,
|
|
243
|
+
type RoutePattern,
|
|
244
|
+
type RoutePatternUsedAsHref,
|
|
245
|
+
type UnknownRoute,
|
|
246
|
+
} from './route-types';
|
|
181
247
|
export { runDoctor, formatDoctorReport, findPantryPackage } from './doctor';
|
|
182
248
|
export {
|
|
183
249
|
applyTranslations,
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,18 @@ export {
|
|
|
6
6
|
useSessionStorage,
|
|
7
7
|
useStorage
|
|
8
8
|
} from "./composables/use-storage.js";
|
|
9
|
+
export {
|
|
10
|
+
clearComposers,
|
|
11
|
+
composer,
|
|
12
|
+
composerPattern,
|
|
13
|
+
runComposers
|
|
14
|
+
} from "./view-composers.js";
|
|
15
|
+
export {
|
|
16
|
+
defineForm,
|
|
17
|
+
useForm,
|
|
18
|
+
v,
|
|
19
|
+
Validator
|
|
20
|
+
} from "./forms-validation.js";
|
|
9
21
|
export { formatSize, getTotalSize } from "./deploy/index.js";
|
|
10
22
|
export { clearImageCache, getFallbackVariant, getMimeType, groupVariantsByFormat, optimizeImage, processImage } from "./image-optimization/index.js";
|
|
11
23
|
export { fileExists } from "./utils.js";
|
|
@@ -44,6 +56,9 @@ export * from "./defer.js";
|
|
|
44
56
|
export * from "./deploy/index.js";
|
|
45
57
|
export * from "./dev-server.js";
|
|
46
58
|
export * from "./document-shell.js";
|
|
59
|
+
export * from "./fragment-container.js";
|
|
60
|
+
export { disableDevTools, enableDevTools } from "./devtools.js";
|
|
61
|
+
export { onUpdate } from "./composables.js";
|
|
47
62
|
export * from "./directive-api.js";
|
|
48
63
|
export * from "./docs.js";
|
|
49
64
|
export * from "./edge-runtime.js";
|
|
@@ -84,6 +99,7 @@ export * from "./suspense.js";
|
|
|
84
99
|
export * from "./teleport.js";
|
|
85
100
|
export * from "./transitions.js";
|
|
86
101
|
export * from "./type-checker.js";
|
|
102
|
+
export * from "./typecheck.js";
|
|
87
103
|
export * from "./web-components.js";
|
|
88
104
|
export * from "./virtual-scrolling.js";
|
|
89
105
|
export * from "./partial-hydration.js";
|
|
@@ -119,6 +135,13 @@ export * from "./dynamic-components.js";
|
|
|
119
135
|
export { definePlugin, pluginManager } from "./plugin-system.js";
|
|
120
136
|
export * from "./render.js";
|
|
121
137
|
export { extractClassNames, generateCrosswindCSS, getCrosswindServeAsset, injectCrosswindCSS } from "./dev-server/crosswind.js";
|
|
138
|
+
export { deepMergeThemes, mergeCrosswindConfig } from "./crosswind-config.js";
|
|
139
|
+
export { clearStoreCache, getStoreScript } from "./store-loader.js";
|
|
140
|
+
export { clearComposableCache } from "./composable-loader.js";
|
|
141
|
+
export { discoverLayoutNames, generateLayoutTypes, LAYOUT_TYPES_FILE, renderLayoutTypes } from "./layout-types.js";
|
|
142
|
+
export {
|
|
143
|
+
$path
|
|
144
|
+
} from "./route-types.js";
|
|
122
145
|
export { runDoctor, formatDoctorReport, findPantryPackage } from "./doctor.js";
|
|
123
146
|
export {
|
|
124
147
|
applyTranslations,
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal markdown utilities to replace ts-md dependency
|
|
3
|
+
* Provides frontmatter parsing and markdown to HTML conversion
|
|
4
|
+
*/
|
|
5
|
+
export interface FrontmatterResult {
|
|
6
|
+
data: Record<string, unknown>;
|
|
7
|
+
content: string;
|
|
8
|
+
}
|
|
9
|
+
export interface MarkdownOptions {
|
|
10
|
+
gfm?: boolean;
|
|
11
|
+
breaks?: boolean;
|
|
12
|
+
}
|
|
1
13
|
/**
|
|
2
14
|
* Parse YAML frontmatter from markdown content
|
|
3
15
|
* Frontmatter is delimited by --- at the start of the file
|
|
@@ -8,11 +20,3 @@ export declare function parseFrontmatter(content: string): FrontmatterResult;
|
|
|
8
20
|
* Simple implementation that handles common markdown patterns
|
|
9
21
|
*/
|
|
10
22
|
export declare function parseMarkdown(content: string, options?: MarkdownOptions): string;
|
|
11
|
-
export declare interface FrontmatterResult {
|
|
12
|
-
data: Record<string, unknown>
|
|
13
|
-
content: string
|
|
14
|
-
}
|
|
15
|
-
export declare interface MarkdownOptions {
|
|
16
|
-
gfm?: boolean
|
|
17
|
-
breaks?: boolean
|
|
18
|
-
}
|
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
/** One extracted island chunk: a content hash and the IIFE it holds. */
|
|
2
|
+
export interface IslandChunk {
|
|
3
|
+
/** Content hash of `code` — the chunk's filename stem (`/_stx/islands/<hash>.js`). */
|
|
4
|
+
hash: string;
|
|
5
|
+
/** The island setup IIFE (trimmed) to write to the chunk file. */
|
|
6
|
+
code: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ExtractIslandChunksResult {
|
|
9
|
+
/** HTML with each inline island IIFE replaced by a `data-stx-src` reference. */
|
|
10
|
+
html: string;
|
|
11
|
+
/** The unique chunks to write (deduped by content hash within the page). */
|
|
12
|
+
chunks: IslandChunk[];
|
|
13
|
+
}
|
|
14
|
+
export interface ExtractIslandChunksOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Stamp `data-stx-integrity="sha384-…"` (Subresource Integrity) on each
|
|
17
|
+
* chunked tag so the runtime can pin the chunk against tampering and a strict
|
|
18
|
+
* CSP can require SRI. Default `false` — only enable when chunks are served
|
|
19
|
+
* byte-for-byte unchanged (no CDN/proxy transform), else the hash won't match
|
|
20
|
+
* and the island silently won't hydrate.
|
|
21
|
+
*/
|
|
22
|
+
integrity?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Minify each chunk's JS (whitespace only) before hashing/writing, so the
|
|
25
|
+
* lazily-loaded bytes aren't padded with source whitespace. Default `false`;
|
|
26
|
+
* the SSG passes its `minify` flag. Hashing happens over the minified bytes,
|
|
27
|
+
* so the content hash + SRI always match what's served.
|
|
28
|
+
*/
|
|
29
|
+
minify?: boolean;
|
|
30
|
+
}
|
|
1
31
|
/**
|
|
2
32
|
* Lift inline island IIFEs into content-hashed chunks. Pure: no filesystem
|
|
3
33
|
* access — the caller writes `result.chunks` and `result.html`.
|
|
@@ -16,16 +46,3 @@ export declare function extractIslandChunks(html: string, options?: ExtractIslan
|
|
|
16
46
|
* not used within N seconds" console warning for below-the-fold islands.
|
|
17
47
|
*/
|
|
18
48
|
export declare function injectIslandChunkPrefetch(html: string): string;
|
|
19
|
-
/** One extracted island chunk: a content hash and the IIFE it holds. */
|
|
20
|
-
export declare interface IslandChunk {
|
|
21
|
-
hash: string
|
|
22
|
-
code: string
|
|
23
|
-
}
|
|
24
|
-
export declare interface ExtractIslandChunksResult {
|
|
25
|
-
html: string
|
|
26
|
-
chunks: IslandChunk[]
|
|
27
|
-
}
|
|
28
|
-
export declare interface ExtractIslandChunksOptions {
|
|
29
|
-
integrity?: boolean
|
|
30
|
-
minify?: boolean
|
|
31
|
-
}
|
package/dist/keep-alive.d.ts
CHANGED
|
@@ -1,3 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* STX Keep-Alive
|
|
3
|
+
*
|
|
4
|
+
* Caches component instances to preserve state when toggling visibility.
|
|
5
|
+
* Similar to Vue's <KeepAlive> component.
|
|
6
|
+
*
|
|
7
|
+
* @module keep-alive
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```html
|
|
11
|
+
* @keepAlive
|
|
12
|
+
* @if (currentTab === 'settings')
|
|
13
|
+
* <SettingsPanel />
|
|
14
|
+
* @elseif (currentTab === 'profile')
|
|
15
|
+
* <ProfilePanel />
|
|
16
|
+
* @endif
|
|
17
|
+
* @endkeepAlive
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* With options:
|
|
21
|
+
* ```html
|
|
22
|
+
* @keepAlive(max: 10, include: 'Settings,Profile', exclude: 'Debug')
|
|
23
|
+
* <component :is="currentComponent" />
|
|
24
|
+
* @endkeepAlive
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export interface KeepAliveOptions {
|
|
28
|
+
/** Maximum number of component instances to cache */
|
|
29
|
+
max?: number;
|
|
30
|
+
/** Comma-separated list of component names to include */
|
|
31
|
+
include?: string;
|
|
32
|
+
/** Comma-separated list of component names to exclude */
|
|
33
|
+
exclude?: string;
|
|
34
|
+
/** Custom cache key */
|
|
35
|
+
id?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface CachedComponent {
|
|
38
|
+
/** Component identifier */
|
|
39
|
+
key: string;
|
|
40
|
+
/** Cached HTML content */
|
|
41
|
+
html: string;
|
|
42
|
+
/** Cached state data */
|
|
43
|
+
state: Record<string, unknown>;
|
|
44
|
+
/** Timestamp when cached */
|
|
45
|
+
cachedAt: number;
|
|
46
|
+
/** Scroll positions */
|
|
47
|
+
scrollPositions: Map<string, {
|
|
48
|
+
top: number;
|
|
49
|
+
left: number;
|
|
50
|
+
}>;
|
|
51
|
+
}
|
|
52
|
+
export interface KeepAliveCache {
|
|
53
|
+
/** Unique cache ID */
|
|
54
|
+
id: string;
|
|
55
|
+
/** Cached components (LRU order) */
|
|
56
|
+
cache: Map<string, CachedComponent>;
|
|
57
|
+
/** Maximum cache size */
|
|
58
|
+
max: number;
|
|
59
|
+
/** Include filter */
|
|
60
|
+
include: string[] | null;
|
|
61
|
+
/** Exclude filter */
|
|
62
|
+
exclude: string[] | null;
|
|
63
|
+
}
|
|
1
64
|
/**
|
|
2
65
|
* Process @keepAlive directives in templates.
|
|
3
66
|
*
|
|
@@ -30,59 +93,16 @@ export declare function generateKeepAliveRuntime(): string;
|
|
|
30
93
|
* Hook called when a component is activated from cache.
|
|
31
94
|
* Use in client-side scripts.
|
|
32
95
|
*/
|
|
33
|
-
export declare function onActivated(callback: (detail: {
|
|
96
|
+
export declare function onActivated(callback: (detail: {
|
|
97
|
+
key: string;
|
|
98
|
+
keepAliveId: string;
|
|
99
|
+
cachedAt: number;
|
|
100
|
+
}) => void): void;
|
|
34
101
|
/**
|
|
35
102
|
* Hook called when a component is deactivated and cached.
|
|
36
103
|
* Use in client-side scripts.
|
|
37
104
|
*/
|
|
38
|
-
export declare function onDeactivated(callback: (detail: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
*
|
|
43
|
-
* Caches component instances to preserve state when toggling visibility.
|
|
44
|
-
* Similar to Vue's <KeepAlive> component.
|
|
45
|
-
*
|
|
46
|
-
* @module keep-alive
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```html
|
|
50
|
-
* @keepAlive
|
|
51
|
-
* @if (currentTab === 'settings')
|
|
52
|
-
* <SettingsPanel />
|
|
53
|
-
* @elseif (currentTab === 'profile')
|
|
54
|
-
* <ProfilePanel />
|
|
55
|
-
* @endif
|
|
56
|
-
* @endkeepAlive
|
|
57
|
-
* ```
|
|
58
|
-
*
|
|
59
|
-
* With options:
|
|
60
|
-
* ```html
|
|
61
|
-
* @keepAlive(max: 10, include: 'Settings,Profile', exclude: 'Debug')
|
|
62
|
-
* <component :is="currentComponent" />
|
|
63
|
-
* @endkeepAlive
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
// =============================================================================
|
|
67
|
-
// Types
|
|
68
|
-
// =============================================================================
|
|
69
|
-
export declare interface KeepAliveOptions {
|
|
70
|
-
max?: number
|
|
71
|
-
include?: string
|
|
72
|
-
exclude?: string
|
|
73
|
-
id?: string
|
|
74
|
-
}
|
|
75
|
-
export declare interface CachedComponent {
|
|
76
|
-
key: string
|
|
77
|
-
html: string
|
|
78
|
-
state: Record<string, unknown>
|
|
79
|
-
cachedAt: number
|
|
80
|
-
scrollPositions: Map<string, { top: number; left: number }>
|
|
81
|
-
}
|
|
82
|
-
export declare interface KeepAliveCache {
|
|
83
|
-
id: string
|
|
84
|
-
cache: Map<string, CachedComponent>
|
|
85
|
-
max: number
|
|
86
|
-
include: string[] | null
|
|
87
|
-
exclude: string[] | null
|
|
88
|
-
}
|
|
105
|
+
export declare function onDeactivated(callback: (detail: {
|
|
106
|
+
key: string;
|
|
107
|
+
keepAliveId: string;
|
|
108
|
+
}) => void): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a union of the layouts that exist on disk, so naming one wrong is a
|
|
3
|
+
* type error rather than an unlayouted page (stacksjs/stx#1879 ask 3).
|
|
4
|
+
*
|
|
5
|
+
* `definePageMeta({ layout: 'app' })` now selects a layout, which makes the
|
|
6
|
+
* name a load-bearing string — and a typo produces exactly the same render as a
|
|
7
|
+
* correct name pointing at a missing file. Nuxt types `layout` as a union of
|
|
8
|
+
* the files on disk for this reason; the failure is caught before the build,
|
|
9
|
+
* not by reading the console afterwards.
|
|
10
|
+
*
|
|
11
|
+
* ## Why this augments the real package, not a synthetic specifier
|
|
12
|
+
*
|
|
13
|
+
* The augmentation targets `@stacksjs/stx`, where `KnownLayouts` is really
|
|
14
|
+
* declared and really referenced by `PageMeta['layout']`.
|
|
15
|
+
*
|
|
16
|
+
* That mattered because the route-type generator used to emit
|
|
17
|
+
* `declare module "stx/routes"` — a specifier nothing in the source tree
|
|
18
|
+
* declares or imports, which TypeScript reads as an ambient module declaration
|
|
19
|
+
* rather than an augmentation. It parsed, shipped, and constrained nothing: the
|
|
20
|
+
* same "typed and never read" shape #1879 is about, one level up. Routes now
|
|
21
|
+
* use this same target (#1887); the reasoning below is what kept this file from
|
|
22
|
+
* repeating it.
|
|
23
|
+
*
|
|
24
|
+
* @module layout-types
|
|
25
|
+
*/
|
|
26
|
+
/** The name of the generated declaration file, inside the state directory. */
|
|
27
|
+
export declare const LAYOUT_TYPES_FILE = "layout-types.d.ts";
|
|
28
|
+
/**
|
|
29
|
+
* Layout names in `layoutsDir`, without the `.stx` extension.
|
|
30
|
+
*
|
|
31
|
+
* Nested layouts keep their path (`admin/settings`), matching what the layout
|
|
32
|
+
* resolver accepts. `_layout.stx` files are excluded: they are applied by
|
|
33
|
+
* directory position, never named.
|
|
34
|
+
*/
|
|
35
|
+
export declare function discoverLayoutNames(layoutsDir: string): string[];
|
|
36
|
+
/** The declaration text for a set of layout names. */
|
|
37
|
+
export declare function renderLayoutTypes(names: readonly string[]): string;
|
|
38
|
+
/**
|
|
39
|
+
* Write the declaration for `layoutsDir` into `outputDir`.
|
|
40
|
+
*
|
|
41
|
+
* Best-effort and idempotent: an unwritable state directory is not a build
|
|
42
|
+
* failure, and an unchanged file is left alone so watchers do not see a write
|
|
43
|
+
* on every render.
|
|
44
|
+
*/
|
|
45
|
+
export declare function generateLayoutTypes(layoutsDir: string | undefined, outputDir: string): string[];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export const LAYOUT_TYPES_FILE = "layout-types.d.ts";
|
|
4
|
+
export function discoverLayoutNames(layoutsDir) {
|
|
5
|
+
const names = [], walk = (dir, prefix) => {
|
|
6
|
+
let entries;
|
|
7
|
+
try {
|
|
8
|
+
entries = fs.readdirSync(dir, { withFileTypes: !0 });
|
|
9
|
+
} catch {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
for (const entry of entries) {
|
|
13
|
+
if (entry.name.startsWith("."))
|
|
14
|
+
continue;
|
|
15
|
+
const full = path.join(dir, entry.name);
|
|
16
|
+
if (entry.isDirectory())
|
|
17
|
+
walk(full, prefix ? `${prefix}/${entry.name}` : entry.name);
|
|
18
|
+
else if (entry.isFile() && entry.name.endsWith(".stx") && entry.name !== "_layout.stx") {
|
|
19
|
+
const base = entry.name.slice(0, -4);
|
|
20
|
+
names.push(prefix ? `${prefix}/${base}` : base);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
walk(layoutsDir, "");
|
|
25
|
+
return names.sort();
|
|
26
|
+
}
|
|
27
|
+
export function renderLayoutTypes(names) {
|
|
28
|
+
const lines = [
|
|
29
|
+
"// Auto-generated by stx \u2014 do not edit.",
|
|
30
|
+
"//",
|
|
31
|
+
"// Makes `definePageMeta({ layout })` reject a name with no layout behind it.",
|
|
32
|
+
"// Include this file in your tsconfig (it lives in the stx state directory,",
|
|
33
|
+
"// `.stx/` by default) for the check to apply.",
|
|
34
|
+
""
|
|
35
|
+
];
|
|
36
|
+
if (names.length === 0) {
|
|
37
|
+
lines.push("// No layouts found \u2014 `layout` stays typed as `string`.", "export {}", "");
|
|
38
|
+
return lines.join(`
|
|
39
|
+
`);
|
|
40
|
+
}
|
|
41
|
+
lines.push("declare module '@stacksjs/stx' {", " interface KnownLayouts {", ...names.map((name) => ` '${name}': true`), " }", "}", "", "export {}", "");
|
|
42
|
+
return lines.join(`
|
|
43
|
+
`);
|
|
44
|
+
}
|
|
45
|
+
export function generateLayoutTypes(layoutsDir, outputDir) {
|
|
46
|
+
if (!layoutsDir)
|
|
47
|
+
return [];
|
|
48
|
+
const abs = path.isAbsolute(layoutsDir) ? layoutsDir : path.resolve(process.cwd(), layoutsDir), names = discoverLayoutNames(abs), contents = renderLayoutTypes(names), target = path.join(outputDir, LAYOUT_TYPES_FILE);
|
|
49
|
+
try {
|
|
50
|
+
if (fs.existsSync(target) && fs.readFileSync(target, "utf8") === contents)
|
|
51
|
+
return names;
|
|
52
|
+
fs.mkdirSync(outputDir, { recursive: !0 });
|
|
53
|
+
fs.writeFileSync(target, contents);
|
|
54
|
+
} catch {}
|
|
55
|
+
return names;
|
|
56
|
+
}
|
package/dist/lazy-module.d.ts
CHANGED
|
@@ -1 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deduplicate cold dynamic imports across concurrent template renders.
|
|
3
|
+
*
|
|
4
|
+
* Bun normally caches evaluated modules, but separate first-use import()
|
|
5
|
+
* calls can still enter its TypeScript compilation path concurrently. A dev
|
|
6
|
+
* server prewarming several routes exposed that race as partial module builds
|
|
7
|
+
* such as "Unexpected end of file" from forms-validation.ts. Keeping the
|
|
8
|
+
* pending promise makes first compilation single-flight while preserving lazy
|
|
9
|
+
* loading and the circular-dependency boundaries that require import().
|
|
10
|
+
*/
|
|
1
11
|
export declare function importOnce<T>(key: string, importer: () => Promise<T>): Promise<T>;
|
package/dist/loops.d.ts
CHANGED
|
@@ -1,3 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module for processing loop directives (@foreach, @for, @while, @forelse)
|
|
3
|
+
*
|
|
4
|
+
* Supports loop control directives:
|
|
5
|
+
* - `@break` - Exit the loop immediately
|
|
6
|
+
* - `@break(condition)` - Exit if condition is true
|
|
7
|
+
* - `@continue` - Skip to next iteration
|
|
8
|
+
* - `@continue(condition)` - Skip if condition is true
|
|
9
|
+
*
|
|
10
|
+
* @foreach syntax variants:
|
|
11
|
+
* - `@foreach(items as item)` - Basic iteration
|
|
12
|
+
* - `@foreach(items as index => item)` - With index variable
|
|
13
|
+
*
|
|
14
|
+
* @example Basic iteration
|
|
15
|
+
* ```html
|
|
16
|
+
* @foreach(items as item)
|
|
17
|
+
* {{ item.name }}
|
|
18
|
+
* @endforeach
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @example With index variable
|
|
22
|
+
* ```html
|
|
23
|
+
* @foreach(items as index => item)
|
|
24
|
+
* {{ index }}: {{ item.name }}
|
|
25
|
+
* @if(index === 0)
|
|
26
|
+
* (first item)
|
|
27
|
+
* @endif
|
|
28
|
+
* @endforeach
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example With loop control
|
|
32
|
+
* ```html
|
|
33
|
+
* @foreach(items as item)
|
|
34
|
+
* @if(item.skip)
|
|
35
|
+
* @continue
|
|
36
|
+
* @endif
|
|
37
|
+
* @if(item.stop)
|
|
38
|
+
* @break
|
|
39
|
+
* @endif
|
|
40
|
+
* {{ item.name }}
|
|
41
|
+
* @endforeach
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
1
44
|
import type { StxOptions } from './types';
|
|
2
45
|
/**
|
|
3
46
|
* Process loops (@foreach, @for, @while, @forelse)
|
|
@@ -22,4 +65,27 @@ import type { StxOptions } from './types';
|
|
|
22
65
|
* @param filePath - Path to template file for error messages
|
|
23
66
|
* @param options - Optional stx configuration
|
|
24
67
|
*/
|
|
68
|
+
/**
|
|
69
|
+
* Split `@foreach(...)` / `@forelse(...)` params into the collection and the
|
|
70
|
+
* item binding.
|
|
71
|
+
*
|
|
72
|
+
* Two spellings are documented and only one was implemented. Blade's
|
|
73
|
+
* `items as item` worked; the JS-natural `item in items` — which
|
|
74
|
+
* docs/SCRIPT_VARIABLES.md shows, and which matches the `:for="item in items"`
|
|
75
|
+
* client directive — did not, and the failure was silent. An unrecognised
|
|
76
|
+
* binding was skipped with `continue`, so the directive text survived into the
|
|
77
|
+
* built page and every `{{ }}` inside it resolved against a variable that never
|
|
78
|
+
* existed. The reported page shipped `data-variant-row="{{ p.id }}"` to the
|
|
79
|
+
* browser: a literal no selector matches and no binding resolves
|
|
80
|
+
* (stacksjs/stx#1842).
|
|
81
|
+
*
|
|
82
|
+
* The operands are the other way round between the two forms, which is the
|
|
83
|
+
* whole reason this needs saying once rather than at each call site. Vue's
|
|
84
|
+
* parenthesised `(item, index)` maps onto the comma form the item parser
|
|
85
|
+
* already understands.
|
|
86
|
+
*/
|
|
87
|
+
export declare function parseLoopBinding(params: string): {
|
|
88
|
+
arrayExpr: string;
|
|
89
|
+
itemVar: string;
|
|
90
|
+
} | null;
|
|
25
91
|
export declare function processLoops(template: string, context: Record<string, any>, filePath: string, options?: StxOptions): string;
|
package/dist/loops.js
CHANGED
|
@@ -4,6 +4,33 @@ import { processExpressions } from "./expressions.js";
|
|
|
4
4
|
import { findDirectiveBlocks, findMatchingDelimiter } from "./parser/index.js";
|
|
5
5
|
import { createSafeFunction, isExpressionSafe, isForExpressionSafe, sanitizeExpression, safeEvaluate, safeEvaluateObject } from "./safe-evaluator.js";
|
|
6
6
|
const DEFAULT_MAX_WHILE_ITERATIONS = 1000, DEFAULT_USE_ALT_LOOP_VARIABLE = !1;
|
|
7
|
+
function preEvaluateIncludeData(content, ctx) {
|
|
8
|
+
const pattern = /@(include|partial)\s*\(\s*(['"])([^'"]+)\2\s*,\s*/g;
|
|
9
|
+
let result = "", lastIndex = 0, match;
|
|
10
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
11
|
+
const argsStart = match.index + match[0].length, openParen = match.index + match[0].indexOf("("), close = findMatchingDelimiter(content, "(", ")", openParen);
|
|
12
|
+
if (close === -1)
|
|
13
|
+
continue;
|
|
14
|
+
const varsString = content.slice(argsStart, close).trim();
|
|
15
|
+
if (!varsString)
|
|
16
|
+
continue;
|
|
17
|
+
if (!Object.keys(ctx).some((name) => new RegExp(`(?:^|[^\\w$.])${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w$])`).test(varsString)))
|
|
18
|
+
continue;
|
|
19
|
+
let frozen;
|
|
20
|
+
try {
|
|
21
|
+
const evaluated = safeEvaluateObject(varsString, ctx);
|
|
22
|
+
if (!evaluated || typeof evaluated !== "object")
|
|
23
|
+
continue;
|
|
24
|
+
frozen = JSON.stringify(evaluated);
|
|
25
|
+
} catch {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
result += content.slice(lastIndex, argsStart) + frozen;
|
|
29
|
+
lastIndex = close;
|
|
30
|
+
pattern.lastIndex = close;
|
|
31
|
+
}
|
|
32
|
+
return lastIndex === 0 ? content : result + content.slice(lastIndex);
|
|
33
|
+
}
|
|
7
34
|
function preEvaluateComponentProps(content, ctx) {
|
|
8
35
|
const componentPat = /@component\s*\(/g;
|
|
9
36
|
let result = content, match;
|
|
@@ -222,10 +249,10 @@ function findOutermostForelse(template) {
|
|
|
222
249
|
}
|
|
223
250
|
if (closeParen === -1)
|
|
224
251
|
continue;
|
|
225
|
-
const params = template.substring(openParen + 1, closeParen),
|
|
226
|
-
if (
|
|
252
|
+
const params = template.substring(openParen + 1, closeParen), binding = parseLoopBinding(params);
|
|
253
|
+
if (!binding)
|
|
227
254
|
continue;
|
|
228
|
-
const arrayExpr
|
|
255
|
+
const { arrayExpr, itemVar } = binding, contentStart = closeParen + 1;
|
|
229
256
|
let depth = 1, searchPos = contentStart;
|
|
230
257
|
const nestedForelseRegex = /@forelse\s*\(/g, endForelseRegex = /@endforelse/g;
|
|
231
258
|
let endForelsePos = -1;
|
|
@@ -310,6 +337,18 @@ function processForelse(template, context) {
|
|
|
310
337
|
}
|
|
311
338
|
return output;
|
|
312
339
|
}
|
|
340
|
+
export function parseLoopBinding(params) {
|
|
341
|
+
const asIndex = params.indexOf(" as ");
|
|
342
|
+
if (asIndex !== -1) {
|
|
343
|
+
const arrayExpr = params.slice(0, asIndex).trim(), itemVar = params.slice(asIndex + 4).trim();
|
|
344
|
+
return arrayExpr && itemVar ? { arrayExpr, itemVar } : null;
|
|
345
|
+
}
|
|
346
|
+
const inMatch = /^\s*(.+?)\s+in\s+([\s\S]+)$/.exec(params);
|
|
347
|
+
if (!inMatch)
|
|
348
|
+
return null;
|
|
349
|
+
const itemVar = inMatch[1].trim().replace(/^\(([\s\S]*)\)$/, "$1").trim(), arrayExpr = inMatch[2].trim();
|
|
350
|
+
return itemVar && arrayExpr ? { arrayExpr, itemVar } : null;
|
|
351
|
+
}
|
|
313
352
|
export function processLoops(template, context, filePath, options) {
|
|
314
353
|
let output = template;
|
|
315
354
|
output = processForelse(output, context);
|
|
@@ -333,10 +372,10 @@ export function processLoops(template, context, filePath, options) {
|
|
|
333
372
|
}
|
|
334
373
|
if (closeParen === -1)
|
|
335
374
|
continue;
|
|
336
|
-
const params = template.substring(openParen + 1, closeParen),
|
|
337
|
-
if (
|
|
375
|
+
const params = template.substring(openParen + 1, closeParen), binding = parseLoopBinding(params);
|
|
376
|
+
if (!binding)
|
|
338
377
|
continue;
|
|
339
|
-
const start = foreachStart, arrayExpr
|
|
378
|
+
const start = foreachStart, { arrayExpr, itemVar } = binding, contentStart = closeParen + 1;
|
|
340
379
|
let depth = 1, searchPos = contentStart;
|
|
341
380
|
const nestedForeachRegex = /@foreach\s*\(/g, endforeachRegex = /@endforeach/g;
|
|
342
381
|
while (depth > 0 && searchPos < template.length) {
|
|
@@ -387,6 +426,7 @@ export function processLoops(template, context, filePath, options) {
|
|
|
387
426
|
array = Object.entries(array);
|
|
388
427
|
isObjectEntries = !0;
|
|
389
428
|
} else {
|
|
429
|
+
console.warn(`[stx] @foreach(${trimmedArrayExpr}) in ${filePath}: ${trimmedArrayExpr} is not iterable server-side, so the loop rendered nothing. ` + "Values a server loop reads must come from <script server> or the page context \u2014 " + "a plain <script> runs in the browser.");
|
|
390
430
|
const errorMsg = inlineError("Foreach", `Error in @foreach: ${trimmedArrayExpr} is not iterable`, ErrorCodes.TYPE_ERROR);
|
|
391
431
|
result = result.substring(0, start) + errorMsg + result.substring(end);
|
|
392
432
|
continue;
|
|
@@ -468,6 +508,7 @@ export function processLoops(template, context, filePath, options) {
|
|
|
468
508
|
processedContent = processExpressions(processedContent, itemContext, filePath);
|
|
469
509
|
processedContent = processPropBindings(processedContent, itemContext);
|
|
470
510
|
processedContent = preEvaluateComponentProps(processedContent, itemContext);
|
|
511
|
+
processedContent = preEvaluateIncludeData(processedContent, itemContext);
|
|
471
512
|
loopResult += processedContent;
|
|
472
513
|
}
|
|
473
514
|
result = result.substring(0, start) + loopResult + result.substring(end);
|
package/dist/markdown.d.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Process markdown directives in templates
|
|
3
3
|
* Converts markdown content to HTML
|
|
4
4
|
*/
|
|
5
|
-
// eslint-disable-next-line pickier/no-unused-vars
|
|
6
5
|
export declare function processMarkdownDirectives(template: string, context: Record<string, any>, filePath?: string): Promise<string>;
|
|
7
6
|
/**
|
|
8
7
|
* Custom directive handler for markdown
|