redweb 0.13.5 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -1
- package/README.md +20 -32
- package/docs/APPLICATION.md +98 -0
- package/docs/CLI.md +1 -1
- package/docs/COVERAGE_SCOPE_AUDIT.md +7 -0
- package/docs/DEFINE_APP_VERIFICATION.md +101 -0
- package/docs/DEVELOPMENT.md +1 -1
- package/docs/GETTING_STARTED.md +1 -1
- package/docs/LIVE_HTML.md +2 -2
- package/docs/MIGRATION.md +1 -1
- package/docs/MULTIPLAYER_OPERATIONS.md +6 -0
- package/docs/RELEASE_TRUST.md +4 -4
- package/docs/RUNTIME_DIAGNOSTICS.md +1 -1
- package/docs/SOCKET_CONTRACTS.md +2 -2
- package/docs/STARTER_LIFECYCLE_VERIFICATION.md +9 -0
- package/docs/generated.json +325 -271
- package/docs/guides/http-websocket.md +4 -4
- package/docs/guides/jsx-without-react.md +1 -1
- package/docs/reference.json +40 -1
- package/docs/releases/0.14.0.json +2208 -0
- package/docs/topics.json +1 -0
- package/examples/live-html/cards.js +87 -86
- package/examples/live-html/cards.ts +3 -2
- package/examples/live-html/chatroom.js +210 -207
- package/examples/live-html/chatroom.tsx +6 -2
- package/examples/live-html/components.js +103 -102
- package/examples/live-html/components.ts +3 -2
- package/examples/live-html/counter.js +74 -73
- package/examples/live-html/counter.ts +3 -2
- package/examples/live-html/jsx-page.js +2 -1
- package/examples/live-html/jsx-page.tsx +3 -2
- package/index.d.ts +53 -5
- package/index.js +3 -0
- package/package.json +3 -3
- package/recipes/chat/app.test.cjs +3 -1
- package/recipes/chat/app.tsx +4 -7
- package/recipes/dashboard/app.test.cjs +10 -10
- package/recipes/dashboard/app.tsx +29 -29
- package/recipes/http-ws/README.md +1 -1
- package/recipes/http-ws/app.test.cjs +8 -10
- package/recipes/http-ws/app.tsx +9 -20
- package/recipes/realtime/app.tsx +3 -6
- package/recipes/shared/README.md +3 -1
- package/recipes/shared/lifecycle.test.cjs +81 -0
- package/recipes/shared/network.cjs +10 -5
- package/recipes/site/app.tsx +3 -6
- package/recipes/socket/app.tsx +3 -10
- package/src/Application.js +239 -0
- package/src/StartupCleanup.js +24 -0
- package/src/cli/SourceInspector.js +5 -0
- package/src/cli/templates.js +3 -4
- package/src/htmx/LiveHtmlServer.js +14 -5
- package/src/htmx/PageManager.js +3 -1
- package/src/ws/BaseSocketServer.js +13 -13
- package/src/ws/SocketRoute.js +6 -2
- package/recipes/shared/run-app.test.cjs +0 -158
- package/recipes/shared/run-app.ts +0 -50
|
@@ -1,113 +1,114 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
3
|
-
var useValue = arguments.length > 2;
|
|
4
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
5
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
6
|
-
}
|
|
7
|
-
return useValue ? value : void 0;
|
|
8
|
-
};
|
|
9
|
-
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
10
|
-
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
11
|
-
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
12
|
-
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
13
|
-
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
14
|
-
var _, done = false;
|
|
15
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
16
|
-
var context = {};
|
|
17
|
-
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
18
|
-
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
19
|
-
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
20
|
-
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
21
|
-
if (kind === "accessor") {
|
|
22
|
-
if (result === void 0) continue;
|
|
23
|
-
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
24
|
-
if (_ = accept(result.get)) descriptor.get = _;
|
|
25
|
-
if (_ = accept(result.set)) descriptor.set = _;
|
|
26
|
-
if (_ = accept(result.init)) initializers.unshift(_);
|
|
27
|
-
}
|
|
28
|
-
else if (_ = accept(result)) {
|
|
29
|
-
if (kind === "field") initializers.unshift(_);
|
|
30
|
-
else descriptor[key] = _;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
34
|
-
done = true;
|
|
35
|
-
};
|
|
36
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
-
exports.ComponentsPage = exports.CounterComponent = void 0;
|
|
38
|
-
const redweb_1 = require('../..');
|
|
39
|
-
let CounterComponent = (() => {
|
|
40
|
-
let _classDecorators = [(0, redweb_1.component)()];
|
|
41
|
-
let _classDescriptor;
|
|
42
|
-
let _classExtraInitializers = [];
|
|
43
|
-
let _classThis;
|
|
44
|
-
let _instanceExtraInitializers = [];
|
|
45
|
-
let _count_decorators;
|
|
46
|
-
let _count_initializers = [];
|
|
47
|
-
let _count_extraInitializers = [];
|
|
48
|
-
let _increment_decorators;
|
|
49
|
-
var CounterComponent = class {
|
|
50
|
-
static { _classThis = this; }
|
|
51
|
-
static {
|
|
52
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
53
|
-
_count_decorators = [(0, redweb_1.state)()];
|
|
54
|
-
_increment_decorators = [(0, redweb_1.action)()];
|
|
55
|
-
__esDecorate(this, null, _increment_decorators, { kind: "method", name: "increment", static: false, private: false, access: { has: obj => "increment" in obj, get: obj => obj.increment }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
56
|
-
__esDecorate(null, null, _count_decorators, { kind: "field", name: "count", static: false, private: false, access: { has: obj => "count" in obj, get: obj => obj.count, set: (obj, value) => { obj.count = value; } }, metadata: _metadata }, _count_initializers, _count_extraInitializers);
|
|
57
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
58
|
-
CounterComponent = _classThis = _classDescriptor.value;
|
|
59
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
60
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
61
|
-
}
|
|
62
|
-
label = __runInitializers(this, _instanceExtraInitializers);
|
|
63
|
-
count = __runInitializers(this, _count_initializers, 0);
|
|
64
|
-
constructor(label) {
|
|
65
|
-
__runInitializers(this, _count_extraInitializers);
|
|
66
|
-
this.label = label;
|
|
67
|
-
}
|
|
68
|
-
increment() {
|
|
69
|
-
this.count += 1;
|
|
70
|
-
}
|
|
71
|
-
render() {
|
|
1
|
+
"use strict";
|
|
2
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
3
|
+
var useValue = arguments.length > 2;
|
|
4
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
5
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
6
|
+
}
|
|
7
|
+
return useValue ? value : void 0;
|
|
8
|
+
};
|
|
9
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
10
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
11
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
12
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
13
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
14
|
+
var _, done = false;
|
|
15
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
16
|
+
var context = {};
|
|
17
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
18
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
19
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
20
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
21
|
+
if (kind === "accessor") {
|
|
22
|
+
if (result === void 0) continue;
|
|
23
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
24
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
25
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
26
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
27
|
+
}
|
|
28
|
+
else if (_ = accept(result)) {
|
|
29
|
+
if (kind === "field") initializers.unshift(_);
|
|
30
|
+
else descriptor[key] = _;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
34
|
+
done = true;
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.ComponentsPage = exports.CounterComponent = void 0;
|
|
38
|
+
const redweb_1 = require('../..');
|
|
39
|
+
let CounterComponent = (() => {
|
|
40
|
+
let _classDecorators = [(0, redweb_1.component)()];
|
|
41
|
+
let _classDescriptor;
|
|
42
|
+
let _classExtraInitializers = [];
|
|
43
|
+
let _classThis;
|
|
44
|
+
let _instanceExtraInitializers = [];
|
|
45
|
+
let _count_decorators;
|
|
46
|
+
let _count_initializers = [];
|
|
47
|
+
let _count_extraInitializers = [];
|
|
48
|
+
let _increment_decorators;
|
|
49
|
+
var CounterComponent = class {
|
|
50
|
+
static { _classThis = this; }
|
|
51
|
+
static {
|
|
52
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
53
|
+
_count_decorators = [(0, redweb_1.state)()];
|
|
54
|
+
_increment_decorators = [(0, redweb_1.action)()];
|
|
55
|
+
__esDecorate(this, null, _increment_decorators, { kind: "method", name: "increment", static: false, private: false, access: { has: obj => "increment" in obj, get: obj => obj.increment }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
56
|
+
__esDecorate(null, null, _count_decorators, { kind: "field", name: "count", static: false, private: false, access: { has: obj => "count" in obj, get: obj => obj.count, set: (obj, value) => { obj.count = value; } }, metadata: _metadata }, _count_initializers, _count_extraInitializers);
|
|
57
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
58
|
+
CounterComponent = _classThis = _classDescriptor.value;
|
|
59
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
60
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
61
|
+
}
|
|
62
|
+
label = __runInitializers(this, _instanceExtraInitializers);
|
|
63
|
+
count = __runInitializers(this, _count_initializers, 0);
|
|
64
|
+
constructor(label) {
|
|
65
|
+
__runInitializers(this, _count_extraInitializers);
|
|
66
|
+
this.label = label;
|
|
67
|
+
}
|
|
68
|
+
increment() {
|
|
69
|
+
this.count += 1;
|
|
70
|
+
}
|
|
71
|
+
render() {
|
|
72
72
|
return (0, redweb_1.html) `
|
|
73
73
|
<article class="counter-card">
|
|
74
74
|
<h2>${this.label}</h2>
|
|
75
75
|
<output data-rw-state="count">${this.count}</output>
|
|
76
76
|
<button type="button" rw-click="increment">Increment on the server</button>
|
|
77
77
|
</article>
|
|
78
|
-
`;
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
return CounterComponent = _classThis;
|
|
82
|
-
})();
|
|
83
|
-
exports.CounterComponent = CounterComponent;
|
|
84
|
-
let ComponentsPage = (() => {
|
|
85
|
-
let _classDecorators = [(0, redweb_1.page)('/', { css: 'components.css' })];
|
|
86
|
-
let _classDescriptor;
|
|
87
|
-
let _classExtraInitializers = [];
|
|
88
|
-
let _classThis;
|
|
89
|
-
var ComponentsPage = class {
|
|
90
|
-
static { _classThis = this; }
|
|
91
|
-
static {
|
|
92
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
93
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
94
|
-
ComponentsPage = _classThis = _classDescriptor.value;
|
|
95
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
96
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
97
|
-
}
|
|
98
|
-
primary = new CounterComponent('Primary counter');
|
|
99
|
-
secondary = new CounterComponent('Independent counter');
|
|
100
|
-
render() {
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
return CounterComponent = _classThis;
|
|
82
|
+
})();
|
|
83
|
+
exports.CounterComponent = CounterComponent;
|
|
84
|
+
let ComponentsPage = (() => {
|
|
85
|
+
let _classDecorators = [(0, redweb_1.page)('/', { css: 'components.css' })];
|
|
86
|
+
let _classDescriptor;
|
|
87
|
+
let _classExtraInitializers = [];
|
|
88
|
+
let _classThis;
|
|
89
|
+
var ComponentsPage = class {
|
|
90
|
+
static { _classThis = this; }
|
|
91
|
+
static {
|
|
92
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
93
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
94
|
+
ComponentsPage = _classThis = _classDescriptor.value;
|
|
95
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
96
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
97
|
+
}
|
|
98
|
+
primary = new CounterComponent('Primary counter');
|
|
99
|
+
secondary = new CounterComponent('Independent counter');
|
|
100
|
+
render() {
|
|
101
101
|
return (0, redweb_1.html) `
|
|
102
102
|
<main>
|
|
103
103
|
<h1>Reusable server components</h1>
|
|
104
104
|
<section class="counter-grid">${this.primary}${this.secondary}</section>
|
|
105
105
|
</main>
|
|
106
|
-
`;
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
return ComponentsPage = _classThis;
|
|
110
|
-
})();
|
|
111
|
-
exports.ComponentsPage = ComponentsPage;
|
|
112
|
-
if (require.main === module)
|
|
113
|
-
(0, redweb_1.
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
return ComponentsPage = _classThis;
|
|
110
|
+
})();
|
|
111
|
+
exports.ComponentsPage = ComponentsPage;
|
|
112
|
+
if (require.main === module)
|
|
113
|
+
void (0, redweb_1.defineApp)({ pages: [ComponentsPage], port: 8080 }).run()
|
|
114
|
+
.catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { action, component, html, page,
|
|
1
|
+
import { action, component, defineApp, html, page, state } from 'redweb';
|
|
2
2
|
|
|
3
3
|
@component()
|
|
4
4
|
export class CounterComponent {
|
|
@@ -38,4 +38,5 @@ export class ComponentsPage {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
if (require.main === module)
|
|
41
|
+
if (require.main === module) void defineApp({ pages: [ComponentsPage], port: 8080 }).run()
|
|
42
|
+
.catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -1,73 +1,74 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
-
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
-
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
-
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
-
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
-
var _, done = false;
|
|
8
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
-
var context = {};
|
|
10
|
-
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
-
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
-
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
-
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
-
if (kind === "accessor") {
|
|
15
|
-
if (result === void 0) continue;
|
|
16
|
-
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
-
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
-
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
-
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
-
}
|
|
21
|
-
else if (_ = accept(result)) {
|
|
22
|
-
if (kind === "field") initializers.unshift(_);
|
|
23
|
-
else descriptor[key] = _;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
-
done = true;
|
|
28
|
-
};
|
|
29
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
-
var useValue = arguments.length > 2;
|
|
31
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
-
}
|
|
34
|
-
return useValue ? value : void 0;
|
|
35
|
-
};
|
|
36
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
-
exports.CounterPage = void 0;
|
|
38
|
-
const redweb_1 = require('../..');
|
|
39
|
-
let CounterPage = (() => {
|
|
40
|
-
let _classDecorators = [(0, redweb_1.page)('/', { template: 'counter.html', css: 'counter.css' })];
|
|
41
|
-
let _classDescriptor;
|
|
42
|
-
let _classExtraInitializers = [];
|
|
43
|
-
let _classThis;
|
|
44
|
-
let _count_decorators;
|
|
45
|
-
let _count_initializers = [];
|
|
46
|
-
let _count_extraInitializers = [];
|
|
47
|
-
var CounterPage = class {
|
|
48
|
-
static { _classThis = this; }
|
|
49
|
-
static {
|
|
50
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
51
|
-
_count_decorators = [(0, redweb_1.state)()];
|
|
52
|
-
__esDecorate(null, null, _count_decorators, { kind: "field", name: "count", static: false, private: false, access: { has: obj => "count" in obj, get: obj => obj.count, set: (obj, value) => { obj.count = value; } }, metadata: _metadata }, _count_initializers, _count_extraInitializers);
|
|
53
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
54
|
-
CounterPage = _classThis = _classDescriptor.value;
|
|
55
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
56
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
57
|
-
}
|
|
58
|
-
count = __runInitializers(this, _count_initializers, 0);
|
|
59
|
-
ticker = (__runInitializers(this, _count_extraInitializers), null);
|
|
60
|
-
connected() {
|
|
61
|
-
this.ticker = setInterval(() => { this.count += 1; }, 1000);
|
|
62
|
-
}
|
|
63
|
-
disconnected() {
|
|
64
|
-
if (this.ticker)
|
|
65
|
-
clearInterval(this.ticker);
|
|
66
|
-
this.ticker = null;
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
return CounterPage = _classThis;
|
|
70
|
-
})();
|
|
71
|
-
exports.CounterPage = CounterPage;
|
|
72
|
-
if (require.main === module)
|
|
73
|
-
(0, redweb_1.
|
|
1
|
+
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.CounterPage = void 0;
|
|
38
|
+
const redweb_1 = require('../..');
|
|
39
|
+
let CounterPage = (() => {
|
|
40
|
+
let _classDecorators = [(0, redweb_1.page)('/', { template: 'counter.html', css: 'counter.css' })];
|
|
41
|
+
let _classDescriptor;
|
|
42
|
+
let _classExtraInitializers = [];
|
|
43
|
+
let _classThis;
|
|
44
|
+
let _count_decorators;
|
|
45
|
+
let _count_initializers = [];
|
|
46
|
+
let _count_extraInitializers = [];
|
|
47
|
+
var CounterPage = class {
|
|
48
|
+
static { _classThis = this; }
|
|
49
|
+
static {
|
|
50
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
51
|
+
_count_decorators = [(0, redweb_1.state)()];
|
|
52
|
+
__esDecorate(null, null, _count_decorators, { kind: "field", name: "count", static: false, private: false, access: { has: obj => "count" in obj, get: obj => obj.count, set: (obj, value) => { obj.count = value; } }, metadata: _metadata }, _count_initializers, _count_extraInitializers);
|
|
53
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
54
|
+
CounterPage = _classThis = _classDescriptor.value;
|
|
55
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
56
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
57
|
+
}
|
|
58
|
+
count = __runInitializers(this, _count_initializers, 0);
|
|
59
|
+
ticker = (__runInitializers(this, _count_extraInitializers), null);
|
|
60
|
+
connected() {
|
|
61
|
+
this.ticker = setInterval(() => { this.count += 1; }, 1000);
|
|
62
|
+
}
|
|
63
|
+
disconnected() {
|
|
64
|
+
if (this.ticker)
|
|
65
|
+
clearInterval(this.ticker);
|
|
66
|
+
this.ticker = null;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
return CounterPage = _classThis;
|
|
70
|
+
})();
|
|
71
|
+
exports.CounterPage = CounterPage;
|
|
72
|
+
if (require.main === module)
|
|
73
|
+
void (0, redweb_1.defineApp)({ pages: [CounterPage], port: 8080 }).run()
|
|
74
|
+
.catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineApp, page, state } from 'redweb';
|
|
2
2
|
|
|
3
3
|
@page('/', { template: 'counter.html', css: 'counter.css' })
|
|
4
4
|
export class CounterPage {
|
|
@@ -18,4 +18,5 @@ export class CounterPage {
|
|
|
18
18
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
if (require.main === module)
|
|
21
|
+
if (require.main === module) void defineApp({ pages: [CounterPage], port: 8080 }).run()
|
|
22
|
+
.catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -78,4 +78,5 @@ let JsxPage = (() => {
|
|
|
78
78
|
})();
|
|
79
79
|
exports.JsxPage = JsxPage;
|
|
80
80
|
if (require.main === module)
|
|
81
|
-
(0, redweb_1.
|
|
81
|
+
void (0, redweb_1.defineApp)({ pages: [JsxPage], port: 8181 }).run()
|
|
82
|
+
.catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LivePage, action, component,
|
|
1
|
+
import { LivePage, action, component, defineApp, page, state } from 'redweb';
|
|
2
2
|
import type { Child } from 'redweb/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
interface CardProperties {
|
|
@@ -38,4 +38,5 @@ export class JsxPage extends LivePage {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
if (require.main === module)
|
|
41
|
+
if (require.main === module) void defineApp({ pages: [JsxPage], port: 8181 }).run()
|
|
42
|
+
.catch(error => { console.error(error); process.exitCode = 1; });
|
package/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare module 'redweb' {
|
|
2
2
|
export { defineSocketContract } from 'redweb/contract';
|
|
3
3
|
export type { SocketContract, ContractClient, SocketSchema, ContractInput, ContractOutput, ContractMessage } from 'redweb/contract';
|
|
4
|
-
import { Application, RequestHandler } from 'express';
|
|
4
|
+
import { Application as ExpressApplication, RequestHandler } from 'express';
|
|
5
5
|
import { CorsOptions } from 'cors';
|
|
6
6
|
import { Server as NodeHttpServer } from 'http';
|
|
7
7
|
import { Server as NodeHttpsServer } from 'https';
|
|
@@ -22,7 +22,7 @@ declare module 'redweb' {
|
|
|
22
22
|
listenCallback?: () => void;
|
|
23
23
|
encoding?: RedWebEncoding;
|
|
24
24
|
ssl?: { key: string; cert: string };
|
|
25
|
-
server?:
|
|
25
|
+
server?: ExpressApplication;
|
|
26
26
|
corsOptions?: CorsOptions | false;
|
|
27
27
|
exposeErrors?: boolean;
|
|
28
28
|
logger?: RedWebLogger | null;
|
|
@@ -287,7 +287,10 @@ declare module 'redweb' {
|
|
|
287
287
|
handlers: Array<new () => BaseHandler>;
|
|
288
288
|
services?: Array<new () => SocketService>;
|
|
289
289
|
allowDuplicateConnections?: boolean;
|
|
290
|
-
websocketOptions?: Omit<ServerOptions, 'noServer' | 'path' | 'server' | 'port'
|
|
290
|
+
websocketOptions?: Omit<ServerOptions, 'noServer' | 'path' | 'server' | 'port'> & {
|
|
291
|
+
/** Closing-handshake deadline in milliseconds (1..2147483647). Default: 5000. Not an idle timeout. */
|
|
292
|
+
closeTimeout?: number;
|
|
293
|
+
};
|
|
291
294
|
trustProxy?: boolean;
|
|
292
295
|
getClientKey?: (request: import('http').IncomingMessage) => string;
|
|
293
296
|
exposeErrors?: boolean;
|
|
@@ -477,7 +480,7 @@ declare module 'redweb' {
|
|
|
477
480
|
}
|
|
478
481
|
|
|
479
482
|
export class BaseHttpServer {
|
|
480
|
-
app:
|
|
483
|
+
app: ExpressApplication;
|
|
481
484
|
server?: NodeHttpServer;
|
|
482
485
|
constructor(options?: RedWebOptions);
|
|
483
486
|
shutdown?(): Promise<void>;
|
|
@@ -653,6 +656,8 @@ declare module 'redweb' {
|
|
|
653
656
|
export type LivePageClass = new () => object;
|
|
654
657
|
|
|
655
658
|
export interface LiveHtmlServerBaseOptions extends Omit<RedWebOptions, 'enableHtmxRendering'> {
|
|
659
|
+
/** Custom routes share the live-page SocketServer; paths must be unique. */
|
|
660
|
+
socketRoutes?: Array<new () => SocketRoute>;
|
|
656
661
|
development?: LiveDevelopmentOptions;
|
|
657
662
|
pages: readonly LivePageClass[];
|
|
658
663
|
templateRoot?: string;
|
|
@@ -682,7 +687,7 @@ declare module 'redweb' {
|
|
|
682
687
|
export type LiveHtmlStartOptions = Omit<LiveHtmlServerBaseOptions, 'pages'> & LiveHtmlAuthentication;
|
|
683
688
|
|
|
684
689
|
export class LiveHtmlServer {
|
|
685
|
-
app:
|
|
690
|
+
app: ExpressApplication;
|
|
686
691
|
server: NodeHttpServer | NodeHttpsServer;
|
|
687
692
|
http: HttpServer | HttpsServer;
|
|
688
693
|
sockets: SocketServer | null;
|
|
@@ -699,6 +704,49 @@ declare module 'redweb' {
|
|
|
699
704
|
options?: LiveHtmlStartOptions
|
|
700
705
|
): LiveHtmlServer;
|
|
701
706
|
|
|
707
|
+
export interface ApplicationContext {
|
|
708
|
+
app: ExpressApplication;
|
|
709
|
+
server: NodeHttpServer | NodeHttpsServer;
|
|
710
|
+
http: HttpServer | HttpsServer;
|
|
711
|
+
sockets: SocketServer | null;
|
|
712
|
+
services: ApplicationService[];
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/** Application-wide resources; route-specific SocketService classes stay on their routes. */
|
|
716
|
+
export interface ApplicationService {
|
|
717
|
+
onInit(app: ApplicationContext, signal: AbortSignal): void | Promise<void>;
|
|
718
|
+
onShutdown(): void | Promise<void>;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
export type ApplicationOptions = Omit<LiveHtmlServerBaseOptions, 'pages' | 'services' | 'listen' | 'socketRoutes'> & LiveHtmlAuthentication & {
|
|
722
|
+
pages?: readonly LivePageClass[];
|
|
723
|
+
sockets?: ReadonlyArray<new () => SocketRoute>;
|
|
724
|
+
services?: ReadonlyArray<new () => ApplicationService>;
|
|
725
|
+
httpServices?: RedWebOptions['services'];
|
|
726
|
+
startupTimeoutMs?: number;
|
|
727
|
+
/** Install process signal handlers only when run() is called; defaults to true. */
|
|
728
|
+
signals?: boolean;
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
export class Application {
|
|
732
|
+
constructor(options?: ApplicationOptions);
|
|
733
|
+
/** Copied definition; use {...app.options, port: 0} to define an independent test instance. */
|
|
734
|
+
readonly options: Readonly<ApplicationOptions>;
|
|
735
|
+
readonly app: ExpressApplication | null;
|
|
736
|
+
readonly server: NodeHttpServer | NodeHttpsServer | null;
|
|
737
|
+
readonly http: HttpServer | HttpsServer | null;
|
|
738
|
+
readonly sockets: SocketServer | null;
|
|
739
|
+
readonly services: ApplicationService[];
|
|
740
|
+
/** Resolves after services initialize and the single HTTP/WS listener is ready. Cannot restart after shutdown. */
|
|
741
|
+
run(): Promise<Application & ApplicationContext>;
|
|
742
|
+
shutdown(): Promise<void>;
|
|
743
|
+
revoke(principal: string | number | bigint | true): Promise<number>;
|
|
744
|
+
inspect(): DevelopmentSnapshot | null;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/** Inert until run(); repeated run calls share startup until shutdown; shutdown is idempotent. */
|
|
748
|
+
export function defineApp(options?: ApplicationOptions): Application;
|
|
749
|
+
|
|
702
750
|
export interface StaticExportOptions {
|
|
703
751
|
outDir: string;
|
|
704
752
|
templateRoot?: string;
|
package/index.js
CHANGED
|
@@ -15,10 +15,13 @@ const {
|
|
|
15
15
|
} = require('./src/ws');
|
|
16
16
|
const { BaseHandler } = require('./src/ws/BaseHandler');
|
|
17
17
|
const { defineSocketContract } = require('./contract');
|
|
18
|
+
const { Application, defineApp } = require('./src/Application');
|
|
18
19
|
const HttpServer = require('./src/http/HttpServer');
|
|
19
20
|
const HttpsServer = require('./src/http/HttpsServer');
|
|
20
21
|
const { action, attribute, codeBlock, component, defineSite, each, exportStatic, html, HtmlRenderer, LiveHtmlServer, LivePage, page, start, state, url, view } = require('./src/htmx');
|
|
21
22
|
module.exports = {
|
|
23
|
+
Application,
|
|
24
|
+
defineApp,
|
|
22
25
|
HttpServer,
|
|
23
26
|
HttpsServer,
|
|
24
27
|
BaseHttpServer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "redweb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "A small Node.js foundation for HTTP, WebSockets, multiplayer services, and server-rendered HTML",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
"verify:client:source-coverage": "node node_modules/jest/bin/jest.js tests/unit/client-source-coverage.unit.test.js tests/integration/client-source-preflight.integration.test.js tests/integration/command-report.integration.test.js --runInBand --coverage --collectCoverageFrom=scripts/lib/ClientSourceCoverage.js --collectCoverageFrom=scripts/lib/reportCommand.js --coverageDirectory=coverage/client-source-collector && node --test tests/integration/client-worker-retention.integration.test.cjs && node scripts/verify-client-source-coverage.js",
|
|
94
94
|
"verify:development:browser": "node scripts/verify-development-refresh-browser.js",
|
|
95
95
|
"verify:development:coverage": "node node_modules/jest/bin/jest.js tests/unit/development-refresh-cleanup.unit.test.js tests/unit/development-refresh-boundaries.unit.test.js tests/integration/development-refresh-verifier.integration.test.js --runInBand --coverage --collectCoverageFrom=scripts/verify-development-refresh-browser.js --coverageDirectory=coverage/development-coordinator",
|
|
96
|
-
"verify:starters:lifecycle": "node
|
|
97
|
-
"verify:starters:lifecycle:coverage": "node node_modules/jest/bin/jest.js tests/unit/
|
|
96
|
+
"verify:starters:lifecycle": "node node_modules/jest/bin/jest.js tests/integration/define-app-process.integration.test.js --runInBand --coverage=false",
|
|
97
|
+
"verify:starters:lifecycle:coverage": "node node_modules/jest/bin/jest.js tests/unit/define-app.unit.test.js tests/unit/define-app-process.unit.test.js tests/unit/startup-cleanup.unit.test.js tests/integration/define-app.integration.test.js tests/integration/define-app-process.integration.test.js --runInBand --coverage --collectCoverageFrom=src/Application.js --collectCoverageFrom=src/StartupCleanup.js --coverageDirectory=coverage/application-lifecycle",
|
|
98
98
|
"measure:starters:coverage": "node scripts/measure-starter-coverage.js",
|
|
99
99
|
"verify:starter-coordinators:coverage": "node node_modules/jest/bin/jest.js tests/unit/starter-coordinators.unit.test.js tests/integration/verification-summary.integration.test.js tests/integration/starter-coordinator-input.integration.test.js --runInBand --silent --coverage --collectCoverageFrom=scripts/measure-starter-coverage.js --collectCoverageFrom=scripts/verify-starter-source-coverage.js --collectCoverageFrom=scripts/lib/finishVerificationSummary.js --coverageDirectory=coverage/starter-coordinators",
|
|
100
100
|
"verify:starters:source-coverage": "node node_modules/jest/bin/jest.js tests/unit/application-coverage.unit.test.js --runInBand --coverage --collectCoverageFrom=scripts/lib/ApplicationCoverage.js --collectCoverageFrom=scripts/lib/assertCoverageFile.js --coverageDirectory=coverage/application-collector && node scripts/verify-starter-source-coverage.js",
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
const test = require('node:test');
|
|
2
2
|
const { once } = require('node:events');
|
|
3
3
|
const assert = require('node:assert/strict');
|
|
4
|
-
const { listen, live, connect } = require('./network.cjs');
|
|
4
|
+
const { listen: listenApp, live, connect } = require('./network.cjs');
|
|
5
5
|
const { createChatroomPage, chatInputs } = require('../dist/chatroom.js');
|
|
6
|
+
// Each test gets an independent room rather than the default module-level room.
|
|
7
|
+
const listen = t => listenApp(t, { pages: [createChatroomPage()] });
|
|
6
8
|
|
|
7
9
|
test('the standalone canonical chat reports an occupied default port', { timeout: 10000 }, async t => {
|
|
8
10
|
const net = require('node:net');
|
package/recipes/chat/app.tsx
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { runApp } from './run-app';
|
|
1
|
+
import { defineApp } from 'redweb';
|
|
2
|
+
import { ChatroomPage } from './chatroom';
|
|
4
3
|
|
|
5
|
-
export
|
|
6
|
-
return start(createChatroomPage(), { port: Number(process.env.PORT ?? 8181), templateRoot: __dirname, ...options });
|
|
7
|
-
}
|
|
4
|
+
export const app = defineApp({ pages: [ChatroomPage], port: Number(process.env.PORT ?? 8181), templateRoot: __dirname });
|
|
8
5
|
|
|
9
|
-
if (require.main === module)
|
|
6
|
+
if (require.main === module) void app.run().catch(error => { console.error(error); process.exitCode = 1; });
|