pulse-js-framework 1.7.13 → 1.7.16
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 +46 -0
- package/cli/help.js +583 -0
- package/cli/index.js +24 -105
- package/package.json +16 -3
- package/runtime/async.js +39 -0
- package/runtime/dom-adapter.js +663 -0
- package/runtime/dom-element.js +107 -0
- package/runtime/index.js +2 -0
- package/runtime/pulse.js +40 -0
- package/runtime/ssr-async.js +229 -0
- package/runtime/ssr-hydrator.js +310 -0
- package/runtime/ssr-serializer.js +266 -0
- package/runtime/ssr.js +463 -0
package/cli/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { dirname, join, resolve, relative } from 'path';
|
|
|
9
9
|
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, watch } from 'fs';
|
|
10
10
|
import { log } from './logger.js';
|
|
11
11
|
import { findPulseFiles, parseArgs } from './utils/file-utils.js';
|
|
12
|
+
import { runHelp } from './help.js';
|
|
12
13
|
|
|
13
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
15
|
const __dirname = dirname(__filename);
|
|
@@ -136,10 +137,28 @@ function suggestCommand(input) {
|
|
|
136
137
|
*/
|
|
137
138
|
async function main() {
|
|
138
139
|
const args = process.argv.slice(2);
|
|
139
|
-
|
|
140
|
+
let command = args[0] || 'help';
|
|
141
|
+
|
|
142
|
+
// Handle global --help and -h flags
|
|
143
|
+
if (command === '--help' || command === '-h') {
|
|
144
|
+
command = 'help';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Handle --version and -v flags
|
|
148
|
+
if (command === '--version' || command === '-v') {
|
|
149
|
+
command = 'version';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Handle command-specific help: pulse <cmd> --help or pulse <cmd> -h
|
|
153
|
+
const cmdArgs = args.slice(1);
|
|
154
|
+
if (cmdArgs.includes('--help') || cmdArgs.includes('-h')) {
|
|
155
|
+
// Show help for the specific command
|
|
156
|
+
await commands.help([command]);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
140
159
|
|
|
141
160
|
if (command in commands) {
|
|
142
|
-
await commands[command](
|
|
161
|
+
await commands[command](cmdArgs);
|
|
143
162
|
} else {
|
|
144
163
|
log.error(`Unknown command: ${command}`);
|
|
145
164
|
|
|
@@ -156,110 +175,10 @@ async function main() {
|
|
|
156
175
|
|
|
157
176
|
/**
|
|
158
177
|
* Show help message
|
|
178
|
+
* Supports: pulse help, pulse help <command>
|
|
159
179
|
*/
|
|
160
|
-
function showHelp() {
|
|
161
|
-
|
|
162
|
-
Pulse Framework CLI v${VERSION}
|
|
163
|
-
|
|
164
|
-
Usage: pulse <command> [options]
|
|
165
|
-
|
|
166
|
-
Commands:
|
|
167
|
-
create <name> Create a new Pulse project
|
|
168
|
-
init [options] Initialize project in current directory
|
|
169
|
-
dev [port] Start development server (default: 3000)
|
|
170
|
-
build Build for production (minified)
|
|
171
|
-
preview [port] Preview production build (default: 4173)
|
|
172
|
-
compile <file> Compile a .pulse file to JavaScript
|
|
173
|
-
mobile <cmd> Mobile app commands (init, build, run)
|
|
174
|
-
lint [files] Validate .pulse files for errors and style
|
|
175
|
-
format [files] Format .pulse files consistently
|
|
176
|
-
analyze Analyze bundle size and dependencies
|
|
177
|
-
test [files] Run tests with coverage support
|
|
178
|
-
doctor Run project diagnostics
|
|
179
|
-
scaffold <type> Generate components, pages, stores
|
|
180
|
-
docs Generate API documentation from JSDoc
|
|
181
|
-
release <type> Create a new release (patch, minor, major)
|
|
182
|
-
docs-test Test documentation (syntax, imports, HTTP)
|
|
183
|
-
version Show version number
|
|
184
|
-
help Show this help message
|
|
185
|
-
|
|
186
|
-
Create/Init Options:
|
|
187
|
-
--typescript Create TypeScript project
|
|
188
|
-
--minimal Create minimal project structure
|
|
189
|
-
|
|
190
|
-
Compile Options:
|
|
191
|
-
--watch, -w Watch files and recompile on changes
|
|
192
|
-
--dry-run Show what would be compiled without writing
|
|
193
|
-
--output, -o Output directory (default: same as input)
|
|
194
|
-
|
|
195
|
-
Lint Options:
|
|
196
|
-
--fix Auto-fix fixable issues
|
|
197
|
-
--watch, -w Watch files and re-lint on changes
|
|
198
|
-
--dry-run Show fixes without applying (use with --fix)
|
|
199
|
-
|
|
200
|
-
Format Options:
|
|
201
|
-
--check Check formatting without writing (dry-run)
|
|
202
|
-
--watch, -w Watch files and re-format on changes
|
|
203
|
-
--write Write formatted output (default)
|
|
204
|
-
|
|
205
|
-
Analyze Options:
|
|
206
|
-
--json Output analysis as JSON
|
|
207
|
-
--verbose Show detailed metrics
|
|
208
|
-
|
|
209
|
-
Test Options:
|
|
210
|
-
--coverage, -c Collect code coverage
|
|
211
|
-
--watch, -w Watch files and re-run tests
|
|
212
|
-
--filter, -f Filter tests by name pattern
|
|
213
|
-
--timeout, -t Test timeout in ms (default: 30000)
|
|
214
|
-
--bail, -b Stop on first failure
|
|
215
|
-
--create <name> Generate a new test file
|
|
216
|
-
|
|
217
|
-
Doctor Options:
|
|
218
|
-
--verbose, -v Show detailed diagnostics
|
|
219
|
-
--json Output as JSON
|
|
220
|
-
|
|
221
|
-
Scaffold Options:
|
|
222
|
-
--dir, -d <path> Output directory
|
|
223
|
-
--force, -f Overwrite existing files
|
|
224
|
-
--props Include props section (components)
|
|
225
|
-
|
|
226
|
-
Docs Options:
|
|
227
|
-
--generate, -g Generate documentation
|
|
228
|
-
--format, -f Output format: markdown, json, html
|
|
229
|
-
--output, -o Output directory (default: docs/api)
|
|
230
|
-
|
|
231
|
-
Release Options:
|
|
232
|
-
--dry-run Show what would be done without making changes
|
|
233
|
-
--no-push Create commit and tag but don't push
|
|
234
|
-
--title <text> Release title for changelog
|
|
235
|
-
--skip-prompt Use empty changelog (for automation)
|
|
236
|
-
--skip-docs-test Skip documentation tests before release
|
|
237
|
-
--from-commits Auto-extract changelog from git commits since last tag
|
|
238
|
-
|
|
239
|
-
Examples:
|
|
240
|
-
pulse create my-app
|
|
241
|
-
pulse create my-app --typescript
|
|
242
|
-
pulse init --typescript
|
|
243
|
-
pulse dev
|
|
244
|
-
pulse build
|
|
245
|
-
pulse test
|
|
246
|
-
pulse test --coverage --watch
|
|
247
|
-
pulse test --create MyComponent
|
|
248
|
-
pulse doctor
|
|
249
|
-
pulse doctor --verbose
|
|
250
|
-
pulse scaffold component Button
|
|
251
|
-
pulse scaffold page Dashboard
|
|
252
|
-
pulse scaffold store user
|
|
253
|
-
pulse docs --generate
|
|
254
|
-
pulse docs --generate --format html
|
|
255
|
-
pulse compile src/App.pulse
|
|
256
|
-
pulse lint src/ --fix
|
|
257
|
-
pulse format --check
|
|
258
|
-
pulse analyze --json
|
|
259
|
-
pulse release patch
|
|
260
|
-
|
|
261
|
-
Documentation: https://github.com/vincenthirtz/pulse-js-framework
|
|
262
|
-
`);
|
|
180
|
+
function showHelp(args = []) {
|
|
181
|
+
runHelp(args);
|
|
263
182
|
}
|
|
264
183
|
|
|
265
184
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pulse-js-framework",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.16",
|
|
4
4
|
"description": "A declarative DOM framework with CSS selector-based structure and reactive pulsations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"./compiler/lexer": "./compiler/lexer.js",
|
|
89
89
|
"./compiler/parser": "./compiler/parser.js",
|
|
90
90
|
"./compiler/transformer": "./compiler/transformer.js",
|
|
91
|
-
"./core/errors": "./
|
|
91
|
+
"./core/errors": "./runtime/errors.js",
|
|
92
92
|
"./vite": {
|
|
93
93
|
"types": "./types/index.d.ts",
|
|
94
94
|
"default": "./loader/vite-plugin.js"
|
|
@@ -109,14 +109,17 @@
|
|
|
109
109
|
"LICENSE"
|
|
110
110
|
],
|
|
111
111
|
"scripts": {
|
|
112
|
-
"test": "npm run test:compiler && npm run test:sourcemap && npm run test:pulse && npm run test:dom && npm run test:dom-adapter && npm run test:router && npm run test:store && npm run test:hmr && npm run test:lint && npm run test:format && npm run test:analyze && npm run test:cli && npm run test:cli-ui && npm run test:lru-cache && npm run test:utils && npm run test:docs && npm run test:async && npm run test:form && npm run test:http && npm run test:devtools && npm run test:native && npm run test:a11y && npm run test:logger && npm run test:errors && npm run test:security && npm run test:websocket && npm run test:graphql && npm run test:doctor && npm run test:scaffold && npm run test:test-runner && npm run test:build",
|
|
112
|
+
"test": "npm run test:compiler && npm run test:sourcemap && npm run test:pulse && npm run test:dom && npm run test:dom-element && npm run test:dom-adapter && npm run test:enhanced-mock-adapter && npm run test:router && npm run test:store && npm run test:context && npm run test:hmr && npm run test:lint && npm run test:format && npm run test:analyze && npm run test:cli && npm run test:cli-ui && npm run test:lru-cache && npm run test:utils && npm run test:docs && npm run test:docs-nav && npm run test:async && npm run test:form && npm run test:http && npm run test:devtools && npm run test:native && npm run test:a11y && npm run test:a11y-enhanced && npm run test:logger && npm run test:errors && npm run test:security && npm run test:websocket && npm run test:graphql && npm run test:doctor && npm run test:scaffold && npm run test:test-runner && npm run test:build && npm run test:integration && npm run test:context-stress && npm run test:form-edge-cases && npm run test:graphql-subscriptions && npm run test:http-edge-cases && npm run test:integration-advanced && npm run test:websocket-stress && npm run test:ssr",
|
|
113
113
|
"test:compiler": "node test/compiler.test.js",
|
|
114
114
|
"test:sourcemap": "node test/sourcemap.test.js",
|
|
115
115
|
"test:pulse": "node test/pulse.test.js",
|
|
116
116
|
"test:dom": "node test/dom.test.js",
|
|
117
|
+
"test:dom-element": "node test/dom-element.test.js",
|
|
117
118
|
"test:dom-adapter": "node test/dom-adapter.test.js",
|
|
119
|
+
"test:enhanced-mock-adapter": "node test/enhanced-mock-adapter.test.js",
|
|
118
120
|
"test:router": "node test/router.test.js",
|
|
119
121
|
"test:store": "node test/store.test.js",
|
|
122
|
+
"test:context": "node test/context.test.js",
|
|
120
123
|
"test:hmr": "node test/hmr.test.js",
|
|
121
124
|
"test:lint": "node test/lint.test.js",
|
|
122
125
|
"test:format": "node test/format.test.js",
|
|
@@ -126,12 +129,14 @@
|
|
|
126
129
|
"test:lru-cache": "node test/lru-cache.test.js",
|
|
127
130
|
"test:utils": "node test/utils.test.js",
|
|
128
131
|
"test:docs": "node test/docs.test.js",
|
|
132
|
+
"test:docs-nav": "node test/docs-navigation.test.js",
|
|
129
133
|
"test:async": "node test/async.test.js",
|
|
130
134
|
"test:form": "node test/form.test.js",
|
|
131
135
|
"test:http": "node test/http.test.js",
|
|
132
136
|
"test:devtools": "node test/devtools.test.js",
|
|
133
137
|
"test:native": "node test/native.test.js",
|
|
134
138
|
"test:a11y": "node test/a11y.test.js",
|
|
139
|
+
"test:a11y-enhanced": "node test/a11y-enhanced.test.js",
|
|
135
140
|
"test:logger": "node test/logger.test.js",
|
|
136
141
|
"test:errors": "node test/errors.test.js",
|
|
137
142
|
"test:security": "node test/security.test.js",
|
|
@@ -141,6 +146,14 @@
|
|
|
141
146
|
"test:scaffold": "node test/scaffold.test.js",
|
|
142
147
|
"test:test-runner": "node test/test-runner.test.js",
|
|
143
148
|
"test:build": "node test/build.test.js",
|
|
149
|
+
"test:integration": "node test/integration.test.js",
|
|
150
|
+
"test:context-stress": "node test/context-stress.test.js",
|
|
151
|
+
"test:form-edge-cases": "node test/form-edge-cases.test.js",
|
|
152
|
+
"test:graphql-subscriptions": "node test/graphql-subscriptions.test.js",
|
|
153
|
+
"test:http-edge-cases": "node test/http-edge-cases.test.js",
|
|
154
|
+
"test:integration-advanced": "node test/integration-advanced.test.js",
|
|
155
|
+
"test:websocket-stress": "node test/websocket-stress.test.js",
|
|
156
|
+
"test:ssr": "node test/ssr.test.js",
|
|
144
157
|
"build:netlify": "node scripts/build-netlify.js",
|
|
145
158
|
"version": "node scripts/sync-version.js",
|
|
146
159
|
"docs": "node cli/index.js dev docs"
|
package/runtime/async.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { pulse, effect, batch, onCleanup } from './pulse.js';
|
|
10
|
+
import { getSSRAsyncContext, registerAsync, getCachedAsync, hasCachedAsync } from './ssr-async.js';
|
|
10
11
|
|
|
11
12
|
// ============================================================================
|
|
12
13
|
// Versioned Async - Centralized Race Condition Handling
|
|
@@ -328,6 +329,44 @@ export function useAsync(asyncFn, options = {}) {
|
|
|
328
329
|
retryDelay = 1000
|
|
329
330
|
} = options;
|
|
330
331
|
|
|
332
|
+
// SSR MODE: Check for cached data or register async operation
|
|
333
|
+
const ssrCtx = getSSRAsyncContext();
|
|
334
|
+
if (ssrCtx) {
|
|
335
|
+
// Check if we already have cached data (second render pass)
|
|
336
|
+
if (hasCachedAsync(asyncFn)) {
|
|
337
|
+
const cachedData = getCachedAsync(asyncFn);
|
|
338
|
+
return {
|
|
339
|
+
data: pulse(cachedData),
|
|
340
|
+
error: pulse(null),
|
|
341
|
+
loading: pulse(false),
|
|
342
|
+
status: pulse('success'),
|
|
343
|
+
execute: () => Promise.resolve(cachedData),
|
|
344
|
+
reset: () => {},
|
|
345
|
+
abort: () => {}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// First render pass: register async operation for collection
|
|
350
|
+
if (immediate) {
|
|
351
|
+
const promise = asyncFn().catch(err => {
|
|
352
|
+
// Store error for SSR error handling
|
|
353
|
+
return null;
|
|
354
|
+
});
|
|
355
|
+
registerAsync(asyncFn, promise);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Return loading state for first pass
|
|
359
|
+
return {
|
|
360
|
+
data: pulse(initialData),
|
|
361
|
+
error: pulse(null),
|
|
362
|
+
loading: pulse(true),
|
|
363
|
+
status: pulse('loading'),
|
|
364
|
+
execute: () => Promise.resolve(initialData),
|
|
365
|
+
reset: () => {},
|
|
366
|
+
abort: () => {}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
|
|
331
370
|
const data = pulse(initialData);
|
|
332
371
|
const error = pulse(null);
|
|
333
372
|
const loading = pulse(false);
|