@absolutejs/absolute 0.19.0-beta.675 → 0.19.0-beta.676
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/angular/components/constants.js +56 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +58 -0
- package/dist/angular/components/core/streamingSlotRegistry.js +114 -0
- package/dist/angular/components/defer-slot-payload.js +6 -0
- package/dist/angular/components/defer-slot-templates.directive.js +44 -0
- package/dist/angular/components/defer-slot.component.js +149 -0
- package/dist/angular/components/image.component.js +202 -0
- package/dist/angular/components/index.js +4 -0
- package/dist/angular/components/stream-slot.component.js +103 -0
- package/dist/cli/index.js +138 -23
- package/dist/index.js +3 -3
- package/dist/index.js.map +4 -4
- package/dist/src/angular/components/constants.d.ts +53 -0
- package/dist/src/utils/defineConfig.d.ts +1 -1
- package/dist/types/build.d.ts +27 -4
- package/package.json +1 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, NgZone, inject, signal } from '@angular/core';
|
|
2
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
3
|
+
import { isStreamingSlotCollectionActive, registerStreamingSlot, warnMissingStreamingSlotCollector } from './core/streamingSlotRegistrar.js';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
const isObjectRecord = (value) => Boolean(value) && typeof value === 'object';
|
|
6
|
+
const isHtmlPayload = (payload) => isObjectRecord(payload) && typeof payload.html === 'string';
|
|
7
|
+
const resolvePayloadHtml = (payload) => {
|
|
8
|
+
if (isHtmlPayload(payload)) {
|
|
9
|
+
return payload.html;
|
|
10
|
+
}
|
|
11
|
+
return typeof payload === 'string' ? payload : '';
|
|
12
|
+
};
|
|
13
|
+
export class StreamSlotComponent {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
16
|
+
this.sanitizer = inject(DomSanitizer);
|
|
17
|
+
this.zone = inject(NgZone);
|
|
18
|
+
this.slotConsumer = (payload) => {
|
|
19
|
+
this.zone.run(() => {
|
|
20
|
+
this.currentHtml.set(this.sanitizer.bypassSecurityTrustHtml(resolvePayloadHtml(payload)));
|
|
21
|
+
this.cdr.markForCheck();
|
|
22
|
+
});
|
|
23
|
+
return true;
|
|
24
|
+
};
|
|
25
|
+
this.fallbackHtml = '';
|
|
26
|
+
this.currentHtml = signal('', ...(ngDevMode ? [{ debugName: "currentHtml" }] : /* istanbul ignore next */ []));
|
|
27
|
+
}
|
|
28
|
+
ngOnInit() {
|
|
29
|
+
if (isStreamingSlotCollectionActive()) {
|
|
30
|
+
this.currentHtml.set(this.sanitizer.bypassSecurityTrustHtml(this.fallbackHtml));
|
|
31
|
+
registerStreamingSlot({
|
|
32
|
+
errorHtml: this.errorHtml,
|
|
33
|
+
fallbackHtml: this.fallbackHtml,
|
|
34
|
+
id: this.id,
|
|
35
|
+
resolve: this.resolve,
|
|
36
|
+
timeoutMs: this.timeoutMs
|
|
37
|
+
});
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
warnMissingStreamingSlotCollector('StreamSlot');
|
|
41
|
+
if (typeof window === 'undefined') {
|
|
42
|
+
this.currentHtml.set(this.sanitizer.bypassSecurityTrustHtml(this.fallbackHtml));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const consumers = (window.__ABS_SLOT_CONSUMERS__ =
|
|
46
|
+
window.__ABS_SLOT_CONSUMERS__ ?? {});
|
|
47
|
+
consumers[this.id] = this.slotConsumer;
|
|
48
|
+
this.currentHtml.set(this.sanitizer.bypassSecurityTrustHtml(this.fallbackHtml));
|
|
49
|
+
const pendingPayload = window.__ABS_SLOT_PENDING__?.[this.id];
|
|
50
|
+
if (pendingPayload !== undefined) {
|
|
51
|
+
this.slotConsumer(pendingPayload);
|
|
52
|
+
delete window.__ABS_SLOT_PENDING__?.[this.id];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
ngOnDestroy() {
|
|
56
|
+
if (typeof window === 'undefined')
|
|
57
|
+
return;
|
|
58
|
+
if (window.__ABS_SLOT_CONSUMERS__) {
|
|
59
|
+
delete window.__ABS_SLOT_CONSUMERS__[this.id];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: StreamSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
63
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: StreamSlotComponent, isStandalone: true, selector: "abs-stream-slot", inputs: { className: "className", errorHtml: "errorHtml", fallbackHtml: "fallbackHtml", id: "id", resolve: "resolve", timeoutMs: "timeoutMs" }, ngImport: i0, template: `
|
|
64
|
+
<div
|
|
65
|
+
[attr.id]="id"
|
|
66
|
+
[attr.class]="className"
|
|
67
|
+
data-absolute-raw-slot="true"
|
|
68
|
+
data-absolute-slot="true"
|
|
69
|
+
[innerHTML]="currentHtml()"
|
|
70
|
+
></div>
|
|
71
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
72
|
+
}
|
|
73
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: StreamSlotComponent, decorators: [{
|
|
74
|
+
type: Component,
|
|
75
|
+
args: [{
|
|
76
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
77
|
+
selector: 'abs-stream-slot',
|
|
78
|
+
standalone: true,
|
|
79
|
+
template: `
|
|
80
|
+
<div
|
|
81
|
+
[attr.id]="id"
|
|
82
|
+
[attr.class]="className"
|
|
83
|
+
data-absolute-raw-slot="true"
|
|
84
|
+
data-absolute-slot="true"
|
|
85
|
+
[innerHTML]="currentHtml()"
|
|
86
|
+
></div>
|
|
87
|
+
`
|
|
88
|
+
}]
|
|
89
|
+
}], propDecorators: { className: [{
|
|
90
|
+
type: Input
|
|
91
|
+
}], errorHtml: [{
|
|
92
|
+
type: Input
|
|
93
|
+
}], fallbackHtml: [{
|
|
94
|
+
type: Input
|
|
95
|
+
}], id: [{
|
|
96
|
+
type: Input,
|
|
97
|
+
args: [{ required: true }]
|
|
98
|
+
}], resolve: [{
|
|
99
|
+
type: Input,
|
|
100
|
+
args: [{ required: true }]
|
|
101
|
+
}], timeoutMs: [{
|
|
102
|
+
type: Input
|
|
103
|
+
}] } });
|
package/dist/cli/index.js
CHANGED
|
@@ -242,9 +242,9 @@ var RESERVED_TOP_LEVEL_KEYS, isObject = (value) => typeof value === "object" &&
|
|
|
242
242
|
cwd: _cwd,
|
|
243
243
|
dependsOn: _dependsOn,
|
|
244
244
|
env: _env,
|
|
245
|
-
healthcheck: _healthcheck,
|
|
246
245
|
kind: _kind,
|
|
247
246
|
port: _port,
|
|
247
|
+
ready: _ready,
|
|
248
248
|
visibility: _visibility,
|
|
249
249
|
...serviceConfig
|
|
250
250
|
} = service;
|
|
@@ -284,7 +284,6 @@ var init_loadConfig = __esm(() => {
|
|
|
284
284
|
"dev",
|
|
285
285
|
"entry",
|
|
286
286
|
"env",
|
|
287
|
-
"healthcheck",
|
|
288
287
|
"htmlDirectory",
|
|
289
288
|
"htmxDirectory",
|
|
290
289
|
"images",
|
|
@@ -301,6 +300,7 @@ var init_loadConfig = __esm(() => {
|
|
|
301
300
|
"stylesConfig",
|
|
302
301
|
"svelteDirectory",
|
|
303
302
|
"tailwind",
|
|
303
|
+
"ready",
|
|
304
304
|
"visibility",
|
|
305
305
|
"vueDirectory"
|
|
306
306
|
]);
|
|
@@ -2482,6 +2482,7 @@ init_constants();
|
|
|
2482
2482
|
init_loadConfig();
|
|
2483
2483
|
init_getDurationString();
|
|
2484
2484
|
import { existsSync as existsSync8, readFileSync as readFileSync8 } from "fs";
|
|
2485
|
+
import { createConnection } from "net";
|
|
2485
2486
|
import { resolve as resolve6 } from "path";
|
|
2486
2487
|
|
|
2487
2488
|
// src/cli/workspaceTui.ts
|
|
@@ -3051,50 +3052,164 @@ var getServiceUrl = (service) => {
|
|
|
3051
3052
|
if (!service.port) {
|
|
3052
3053
|
return null;
|
|
3053
3054
|
}
|
|
3054
|
-
return
|
|
3055
|
+
return `${getServiceProtocol(service)}://${getServicePublicHost(service)}:${service.port}/`;
|
|
3055
3056
|
};
|
|
3056
|
-
var
|
|
3057
|
-
if (service.healthcheck) {
|
|
3058
|
-
return service.healthcheck;
|
|
3059
|
-
}
|
|
3057
|
+
var getDefaultReadyConfig = (service) => {
|
|
3060
3058
|
if (isAbsoluteService(service) && service.port) {
|
|
3061
|
-
return
|
|
3059
|
+
return "/hmr-status";
|
|
3062
3060
|
}
|
|
3063
3061
|
return;
|
|
3064
3062
|
};
|
|
3065
|
-
var
|
|
3066
|
-
|
|
3067
|
-
|
|
3063
|
+
var normalizeExpectedStatuses = (value) => Array.isArray(value) ? value : [value ?? 200];
|
|
3064
|
+
var resolveServiceHttpUrl = (service, path) => {
|
|
3065
|
+
if (!path.startsWith("/")) {
|
|
3066
|
+
throw new Error(`ready path must start with "/" for service probes. Received "${path}".`);
|
|
3068
3067
|
}
|
|
3069
|
-
if (
|
|
3068
|
+
if (!service.port) {
|
|
3069
|
+
throw new Error(`ready path "${path}" requires the service to define a port.`);
|
|
3070
|
+
}
|
|
3071
|
+
return `${getServiceProtocol(service)}://${getServicePublicHost(service)}:${service.port}${path}`;
|
|
3072
|
+
};
|
|
3073
|
+
var resolveHttpReadyProbe = (service, ready) => {
|
|
3074
|
+
if (typeof ready === "string") {
|
|
3075
|
+
if (isAbsoluteService(service)) {
|
|
3076
|
+
return {
|
|
3077
|
+
type: "http",
|
|
3078
|
+
url: resolveServiceHttpUrl(service, ready),
|
|
3079
|
+
method: "GET",
|
|
3080
|
+
expectStatus: [200],
|
|
3081
|
+
headers: {},
|
|
3082
|
+
intervalMs: 250,
|
|
3083
|
+
timeoutMs: 30000
|
|
3084
|
+
};
|
|
3085
|
+
}
|
|
3070
3086
|
return {
|
|
3087
|
+
type: "http",
|
|
3088
|
+
url: ready,
|
|
3089
|
+
method: "GET",
|
|
3090
|
+
expectStatus: [200],
|
|
3091
|
+
headers: {},
|
|
3071
3092
|
intervalMs: 250,
|
|
3072
|
-
timeoutMs: 30000
|
|
3073
|
-
url: healthcheck
|
|
3093
|
+
timeoutMs: 30000
|
|
3074
3094
|
};
|
|
3075
3095
|
}
|
|
3096
|
+
if (ready.path && ready.url) {
|
|
3097
|
+
throw new Error('ready HTTP probe cannot define both "path" and "url".');
|
|
3098
|
+
}
|
|
3099
|
+
const url = ready.path ? resolveServiceHttpUrl(service, ready.path) : ready.url ? ready.url : isAbsoluteService(service) ? resolveServiceHttpUrl(service, "/hmr-status") : null;
|
|
3100
|
+
if (!url) {
|
|
3101
|
+
throw new Error('ready HTTP probe requires either "url" or "path".');
|
|
3102
|
+
}
|
|
3076
3103
|
return {
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3104
|
+
type: "http",
|
|
3105
|
+
url,
|
|
3106
|
+
method: ready.method ?? "GET",
|
|
3107
|
+
expectStatus: normalizeExpectedStatuses(ready.expectStatus),
|
|
3108
|
+
headers: ready.headers ?? {},
|
|
3109
|
+
intervalMs: ready.intervalMs ?? 250,
|
|
3110
|
+
timeoutMs: ready.timeoutMs ?? 30000
|
|
3080
3111
|
};
|
|
3081
3112
|
};
|
|
3082
|
-
var
|
|
3083
|
-
|
|
3113
|
+
var resolveReadyProbe = (service, ready = service.ready ?? getDefaultReadyConfig(service)) => {
|
|
3114
|
+
if (ready === false || !ready) {
|
|
3115
|
+
return null;
|
|
3116
|
+
}
|
|
3117
|
+
if (typeof ready === "string") {
|
|
3118
|
+
return resolveHttpReadyProbe(service, ready);
|
|
3119
|
+
}
|
|
3120
|
+
if (ready.type === "tcp") {
|
|
3121
|
+
return {
|
|
3122
|
+
type: "tcp",
|
|
3123
|
+
host: ready.host ?? getServicePublicHost(service),
|
|
3124
|
+
port: ready.port,
|
|
3125
|
+
intervalMs: ready.intervalMs ?? 250,
|
|
3126
|
+
timeoutMs: ready.timeoutMs ?? 30000
|
|
3127
|
+
};
|
|
3128
|
+
}
|
|
3129
|
+
if (ready.type === "command") {
|
|
3130
|
+
return {
|
|
3131
|
+
type: "command",
|
|
3132
|
+
command: ready.command,
|
|
3133
|
+
intervalMs: ready.intervalMs ?? 250,
|
|
3134
|
+
timeoutMs: ready.timeoutMs ?? 30000
|
|
3135
|
+
};
|
|
3136
|
+
}
|
|
3137
|
+
if (ready.type === "delay") {
|
|
3138
|
+
return {
|
|
3139
|
+
type: "delay",
|
|
3140
|
+
ms: ready.ms
|
|
3141
|
+
};
|
|
3142
|
+
}
|
|
3143
|
+
return resolveHttpReadyProbe(service, ready);
|
|
3144
|
+
};
|
|
3145
|
+
var probeHttpReady = async (ready) => {
|
|
3146
|
+
const response = await fetch(ready.url, {
|
|
3147
|
+
method: ready.method,
|
|
3148
|
+
headers: ready.headers,
|
|
3149
|
+
signal: AbortSignal.timeout(Math.min(ready.timeoutMs, 5000))
|
|
3150
|
+
});
|
|
3151
|
+
return ready.expectStatus.includes(response.status);
|
|
3152
|
+
};
|
|
3153
|
+
var probeTcpReady = async (ready) => new Promise((resolveProbe) => {
|
|
3154
|
+
const socket = createConnection({
|
|
3155
|
+
host: ready.host,
|
|
3156
|
+
port: ready.port
|
|
3157
|
+
});
|
|
3158
|
+
const timeout = setTimeout(() => {
|
|
3159
|
+
socket.destroy();
|
|
3160
|
+
resolveProbe(false);
|
|
3161
|
+
}, Math.min(ready.timeoutMs, 5000));
|
|
3162
|
+
socket.once("connect", () => {
|
|
3163
|
+
clearTimeout(timeout);
|
|
3164
|
+
socket.end();
|
|
3165
|
+
resolveProbe(true);
|
|
3166
|
+
});
|
|
3167
|
+
socket.once("error", () => {
|
|
3168
|
+
clearTimeout(timeout);
|
|
3169
|
+
socket.destroy();
|
|
3170
|
+
resolveProbe(false);
|
|
3171
|
+
});
|
|
3172
|
+
});
|
|
3173
|
+
var probeCommandReady = async (ready, service) => {
|
|
3174
|
+
const processHandle = Bun.spawn(ready.command, {
|
|
3175
|
+
cwd: service.cwd,
|
|
3176
|
+
env: service.env,
|
|
3177
|
+
stderr: "ignore",
|
|
3178
|
+
stdin: "ignore",
|
|
3179
|
+
stdout: "ignore"
|
|
3180
|
+
});
|
|
3181
|
+
const timeout = setTimeout(() => {
|
|
3182
|
+
try {
|
|
3183
|
+
processHandle.kill();
|
|
3184
|
+
} catch {}
|
|
3185
|
+
}, Math.min(ready.timeoutMs, 5000));
|
|
3186
|
+
try {
|
|
3187
|
+
const exitCode = await processHandle.exited;
|
|
3188
|
+
return exitCode === 0;
|
|
3189
|
+
} finally {
|
|
3190
|
+
clearTimeout(timeout);
|
|
3191
|
+
}
|
|
3192
|
+
};
|
|
3193
|
+
var waitForReady = async (service) => {
|
|
3194
|
+
const resolved = resolveReadyProbe(service.service);
|
|
3084
3195
|
if (!resolved) {
|
|
3085
3196
|
return;
|
|
3086
3197
|
}
|
|
3198
|
+
if (resolved.type === "delay") {
|
|
3199
|
+
await sleep(resolved.ms);
|
|
3200
|
+
return;
|
|
3201
|
+
}
|
|
3087
3202
|
const startedAt = Date.now();
|
|
3088
3203
|
while (Date.now() - startedAt < resolved.timeoutMs) {
|
|
3089
3204
|
try {
|
|
3090
|
-
const
|
|
3091
|
-
if (
|
|
3205
|
+
const isReady = resolved.type === "http" ? await probeHttpReady(resolved) : resolved.type === "tcp" ? await probeTcpReady(resolved) : await probeCommandReady(resolved, service);
|
|
3206
|
+
if (isReady) {
|
|
3092
3207
|
return;
|
|
3093
3208
|
}
|
|
3094
3209
|
} catch {}
|
|
3095
3210
|
await sleep(resolved.intervalMs);
|
|
3096
3211
|
}
|
|
3097
|
-
throw new Error(`service did not become
|
|
3212
|
+
throw new Error(resolved.type === "http" ? `service did not become ready within ${resolved.timeoutMs}ms (${resolved.url})` : resolved.type === "tcp" ? `service did not become ready within ${resolved.timeoutMs}ms (tcp://${resolved.host}:${resolved.port})` : `service did not become ready within ${resolved.timeoutMs}ms (${resolved.command.join(" ")})`);
|
|
3098
3213
|
};
|
|
3099
3214
|
var topologicallySortServices = (services) => {
|
|
3100
3215
|
const ordered = [];
|
|
@@ -3341,7 +3456,7 @@ var workspace = async (subcommand, options) => {
|
|
|
3341
3456
|
tui.addLog("workspace", `${name} exited with code ${exitCode || 1}. Shutting down workspace.`, "error");
|
|
3342
3457
|
shutdown(exitCode || 1);
|
|
3343
3458
|
});
|
|
3344
|
-
await
|
|
3459
|
+
await waitForReady(resolved);
|
|
3345
3460
|
const startedAt = serviceBootStartedAt.get(name);
|
|
3346
3461
|
const readyDuration = typeof startedAt === "number" ? `ready in ${getDurationString(performance.now() - startedAt)}` : undefined;
|
|
3347
3462
|
tui.setServiceStatus(name, "ready", readyDuration);
|
package/dist/index.js
CHANGED
|
@@ -181936,7 +181936,6 @@ var RESERVED_TOP_LEVEL_KEYS = new Set([
|
|
|
181936
181936
|
"dev",
|
|
181937
181937
|
"entry",
|
|
181938
181938
|
"env",
|
|
181939
|
-
"healthcheck",
|
|
181940
181939
|
"htmlDirectory",
|
|
181941
181940
|
"htmxDirectory",
|
|
181942
181941
|
"images",
|
|
@@ -181953,6 +181952,7 @@ var RESERVED_TOP_LEVEL_KEYS = new Set([
|
|
|
181953
181952
|
"stylesConfig",
|
|
181954
181953
|
"svelteDirectory",
|
|
181955
181954
|
"tailwind",
|
|
181955
|
+
"ready",
|
|
181956
181956
|
"visibility",
|
|
181957
181957
|
"vueDirectory"
|
|
181958
181958
|
]);
|
|
@@ -181993,9 +181993,9 @@ var projectServiceConfig = (config, serviceName) => {
|
|
|
181993
181993
|
cwd: _cwd,
|
|
181994
181994
|
dependsOn: _dependsOn,
|
|
181995
181995
|
env: _env,
|
|
181996
|
-
healthcheck: _healthcheck,
|
|
181997
181996
|
kind: _kind,
|
|
181998
181997
|
port: _port,
|
|
181998
|
+
ready: _ready,
|
|
181999
181999
|
visibility: _visibility,
|
|
182000
182000
|
...serviceConfig
|
|
182001
182001
|
} = service;
|
|
@@ -188898,5 +188898,5 @@ export {
|
|
|
188898
188898
|
ANGULAR_INIT_TIMEOUT_MS
|
|
188899
188899
|
};
|
|
188900
188900
|
|
|
188901
|
-
//# debugId=
|
|
188901
|
+
//# debugId=97D769D373BB628F64756E2164756E21
|
|
188902
188902
|
//# sourceMappingURL=index.js.map
|