tungsten 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Components.d.ts +3 -1
- package/dist/Components.d.ts.map +1 -1
- package/dist/Components.js +100 -51
- package/dist/DomNodes.js +2 -2
- package/dist/FrameworkConfig.d.ts +2 -0
- package/dist/FrameworkConfig.d.ts.map +1 -1
- package/dist/FunctionComponentStandIn.d.ts +2 -0
- package/dist/FunctionComponentStandIn.d.ts.map +1 -1
- package/dist/FunctionComponentStandIn.js +16 -3
- package/dist/Instance/ClientRuntimeContext.d.ts +8 -0
- package/dist/Instance/ClientRuntimeContext.d.ts.map +1 -0
- package/dist/Instance/ClientRuntimeContext.js +1 -0
- package/dist/Instance/Instance.d.ts +20 -1
- package/dist/Instance/Instance.d.ts.map +1 -1
- package/dist/Instance/Instance.js +59 -11
- package/dist/Servers/loadEnvsDev.d.ts +1 -1
- package/dist/Servers/loadEnvsDev.d.ts.map +1 -1
- package/dist/Servers/loadEnvsDev.js +18 -3
- package/dist/Store/makeStore.d.ts.map +1 -1
- package/dist/Store/makeStore.js +7 -14
- package/dist/babelPlugins/BabelTransformPackageImports.d.ts +1 -0
- package/dist/babelPlugins/BabelTransformPackageImports.d.ts.map +1 -1
- package/dist/babelPlugins/BabelTransformPackageImports.js +109 -70
- package/dist/bin/commands/compile.sxyt.js +76 -1
- package/dist/build/compileJavascript.d.ts.map +1 -1
- package/dist/build/compileJavascript.js +13 -1
- package/dist/build/makeBabelUserDevConfig.d.ts +1 -1
- package/dist/build/makeBabelUserDevConfig.d.ts.map +1 -1
- package/dist/build/makeBabelUserDevConfig.js +2 -1
- package/dist/findUserConfig.d.ts +1 -1
- package/dist/findUserConfig.d.ts.map +1 -1
- package/dist/findUserConfig.js +2 -2
- package/dist/frameworkConfigSchema.d.ts +4 -0
- package/dist/frameworkConfigSchema.d.ts.map +1 -1
- package/dist/frameworkConfigSchema.js +1 -0
- package/dist/getUserConfig.d.ts +1 -1
- package/dist/getUserConfig.d.ts.map +1 -1
- package/dist/getUserConfig.js +2 -2
- package/dist/hooks/useState.js +1 -1
- package/dist/indexInner.d.ts +0 -1
- package/dist/indexInner.d.ts.map +1 -1
- package/dist/indexInner.js +1 -1
- package/dist/testing/createTestApp.sxyt.d.ts +2 -0
- package/dist/testing/createTestApp.sxyt.d.ts.map +1 -0
- package/dist/testing/createTestApp.sxyt.js +424 -0
- package/dist/testing/ensureTestEnvLoaded.d.ts +2 -0
- package/dist/testing/ensureTestEnvLoaded.d.ts.map +1 -0
- package/dist/testing/ensureTestEnvLoaded.js +19 -0
- package/dist/testing/index.d.ts +36 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +156 -0
- package/dist/update/UpdateScheduler.d.ts +17 -0
- package/dist/update/UpdateScheduler.d.ts.map +1 -0
- package/dist/update/UpdateScheduler.js +113 -0
- package/dist/update/integrateUpdateVdom.d.ts +11 -1
- package/dist/update/integrateUpdateVdom.d.ts.map +1 -1
- package/dist/update/integrateUpdateVdom.js +117 -59
- package/dist/{react-zone.d.ts → zones/react.d.ts} +5 -5
- package/dist/zones/react.d.ts.map +1 -0
- package/dist/{react-zone.js → zones/react.js} +3 -3
- package/package.json +4 -2
- package/readme.md +80 -0
- package/dist/react-zone.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensureTestEnvLoaded.d.ts","sourceRoot":"","sources":["../../src/testing/ensureTestEnvLoaded.ts"],"names":[],"mappings":"AASA,wBAAgB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAWnD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getUserConfig } from "../getUserConfig.js";
|
|
2
|
+
import { loadEnvsDev } from "../Servers/loadEnvsDev.js";
|
|
3
|
+
let loadPromise;
|
|
4
|
+
// Populate global.tungstenPublicEnv / global.tungstenPrivateEnv for DOM component
|
|
5
|
+
// tests, exactly once per process. Compiled client component code reads these as
|
|
6
|
+
// bare globals, so they must exist before any component runs under the test runner.
|
|
7
|
+
// Test runs prefer .env.test* files (per-file replacement) via useTestEnvFiles.
|
|
8
|
+
export function ensureTestEnvLoaded() {
|
|
9
|
+
if (loadPromise === undefined) {
|
|
10
|
+
loadPromise = (async () => {
|
|
11
|
+
const config = await getUserConfig('silent');
|
|
12
|
+
// iteration 0: schemas are stable within a test run.
|
|
13
|
+
// _firstLoad = false: suppress the CLI boot output.
|
|
14
|
+
// useTestEnvFiles = true: prefer .env.test* files.
|
|
15
|
+
await loadEnvsDev(config, 0, process.env, false, true);
|
|
16
|
+
})();
|
|
17
|
+
}
|
|
18
|
+
return loadPromise;
|
|
19
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { TungstenBaseComponent, TungstenBaseComponentType } from '../Components.jsx';
|
|
2
|
+
import type { TrueStore } from '../Store/makeStore.js';
|
|
3
|
+
export type ComponentProps<ComponentType extends TungstenBaseComponentType<any, any>> = InstanceType<ComponentType>['props'];
|
|
4
|
+
export type TestStoreRegistration<Schema extends object> = {
|
|
5
|
+
getStore: (stores: TrueStore<unknown>[]) => TrueStore<Schema>;
|
|
6
|
+
};
|
|
7
|
+
export type TestStore<Schema extends object> = TrueStore<Schema>;
|
|
8
|
+
export type TestStoreOverride<Schema extends object = object> = {
|
|
9
|
+
registration: TestStoreRegistration<Schema>;
|
|
10
|
+
initialize: (store: TrueStore<Schema>) => void | Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
export declare function testStore<Schema extends object>(registration: TestStoreRegistration<Schema>, initialize: (store: TestStore<Schema>) => void | Promise<void>): TestStoreOverride<Schema>;
|
|
13
|
+
export type TestAppOptions<Props extends object> = {
|
|
14
|
+
document?: Document;
|
|
15
|
+
props?: Props;
|
|
16
|
+
container?: HTMLElement;
|
|
17
|
+
location?: string;
|
|
18
|
+
routeParams?: Record<string, string>;
|
|
19
|
+
routeData?: unknown;
|
|
20
|
+
globalData?: Record<string, unknown>;
|
|
21
|
+
stores?: readonly TestStoreOverride<any>[];
|
|
22
|
+
};
|
|
23
|
+
export type TestApp<Component extends TungstenBaseComponent> = {
|
|
24
|
+
readonly document: Document;
|
|
25
|
+
readonly container: HTMLElement;
|
|
26
|
+
readonly component: Component;
|
|
27
|
+
resolved(): Promise<void>;
|
|
28
|
+
setProps(props: Component['props']): Promise<void>;
|
|
29
|
+
unmount(): Promise<void>;
|
|
30
|
+
};
|
|
31
|
+
type CreateTestAppArgs<Props extends object> = object extends Props ? [options?: TestAppOptions<Props>] : keyof Props extends never ? [options?: TestAppOptions<Props>] : [options: TestAppOptions<Props> & {
|
|
32
|
+
props: Props;
|
|
33
|
+
}];
|
|
34
|
+
export declare function createTestApp<ComponentType extends TungstenBaseComponentType<any, any>>(RootComponent: ComponentType, ...args: CreateTestAppArgs<ComponentProps<ComponentType>>): Promise<TestApp<InstanceType<ComponentType>>>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
|
|
2
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
3
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
4
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
5
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
|
+
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
|
|
7
|
+
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
|
|
8
|
+
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
9
|
+
import { Instance } from "../Instance/Instance.js";
|
|
10
|
+
import { initStores } from "../Servers/initStores.js";
|
|
11
|
+
import { ensureTestEnvLoaded } from "./ensureTestEnvLoaded.js";
|
|
12
|
+
import { createTungstenRootComponent, deleteTungstenRoot } from "../update/integrateUpdateVdom.js";
|
|
13
|
+
import { UpdateScheduler } from "../update/UpdateScheduler.js";
|
|
14
|
+
export function testStore(registration, initialize) {
|
|
15
|
+
return {
|
|
16
|
+
registration,
|
|
17
|
+
initialize
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
var _instance = /*#__PURE__*/new WeakMap();
|
|
21
|
+
var _scheduler = /*#__PURE__*/new WeakMap();
|
|
22
|
+
var _root = /*#__PURE__*/new WeakMap();
|
|
23
|
+
var _ownsContainer = /*#__PURE__*/new WeakMap();
|
|
24
|
+
var _unmounted = /*#__PURE__*/new WeakMap();
|
|
25
|
+
class TestAppImplementation {
|
|
26
|
+
constructor(document, container, component, instance, scheduler, root, ownsContainer) {
|
|
27
|
+
_defineProperty(this, "document", void 0);
|
|
28
|
+
_defineProperty(this, "container", void 0);
|
|
29
|
+
_defineProperty(this, "component", void 0);
|
|
30
|
+
_classPrivateFieldInitSpec(this, _instance, void 0);
|
|
31
|
+
_classPrivateFieldInitSpec(this, _scheduler, void 0);
|
|
32
|
+
_classPrivateFieldInitSpec(this, _root, void 0);
|
|
33
|
+
_classPrivateFieldInitSpec(this, _ownsContainer, void 0);
|
|
34
|
+
_classPrivateFieldInitSpec(this, _unmounted, false);
|
|
35
|
+
_defineProperty(this, "resolved", async () => {
|
|
36
|
+
await _classPrivateFieldGet(_scheduler, this).resolved();
|
|
37
|
+
});
|
|
38
|
+
_defineProperty(this, "setProps", async props => {
|
|
39
|
+
if (_classPrivateFieldGet(_unmounted, this)) throw new Error('Cannot set props on an unmounted Tungsten TestApp.');
|
|
40
|
+
this.component.props = props;
|
|
41
|
+
_classPrivateFieldGet(_instance, this).queueUpdate(this.component);
|
|
42
|
+
await this.resolved();
|
|
43
|
+
});
|
|
44
|
+
_defineProperty(this, "unmount", async () => {
|
|
45
|
+
if (_classPrivateFieldGet(_unmounted, this)) return;
|
|
46
|
+
_classPrivateFieldSet(_unmounted, this, true);
|
|
47
|
+
_classPrivateFieldGet(_scheduler, this).cancelPending();
|
|
48
|
+
let cleanupError;
|
|
49
|
+
try {
|
|
50
|
+
deleteTungstenRoot(_classPrivateFieldGet(_root, this));
|
|
51
|
+
_classPrivateFieldGet(_instance, this).disposeRegisteredComponents();
|
|
52
|
+
await _classPrivateFieldGet(_scheduler, this).resolved();
|
|
53
|
+
} catch (error) {
|
|
54
|
+
cleanupError = error;
|
|
55
|
+
try {
|
|
56
|
+
_classPrivateFieldGet(_instance, this).disposeRegisteredComponents();
|
|
57
|
+
} catch {
|
|
58
|
+
// Preserve the first cleanup failure.
|
|
59
|
+
}
|
|
60
|
+
} finally {
|
|
61
|
+
_classPrivateFieldGet(_scheduler, this).dispose();
|
|
62
|
+
if (_classPrivateFieldGet(_ownsContainer, this)) this.container.remove();else while (this.container.firstChild !== null) this.container.removeChild(this.container.firstChild);
|
|
63
|
+
}
|
|
64
|
+
if (cleanupError !== undefined) throw cleanupError;
|
|
65
|
+
});
|
|
66
|
+
this.document = document;
|
|
67
|
+
this.container = container;
|
|
68
|
+
this.component = component;
|
|
69
|
+
_classPrivateFieldSet(_instance, this, instance);
|
|
70
|
+
_classPrivateFieldSet(_scheduler, this, scheduler);
|
|
71
|
+
_classPrivateFieldSet(_root, this, root);
|
|
72
|
+
_classPrivateFieldSet(_ownsContainer, this, ownsContainer);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export async function createTestApp(RootComponent, ...args) {
|
|
76
|
+
await ensureTestEnvLoaded();
|
|
77
|
+
const options = args[0];
|
|
78
|
+
const suppliedDocument = options?.document ?? globalThis.document;
|
|
79
|
+
if (suppliedDocument === undefined) {
|
|
80
|
+
// eslint-disable-line @typescript-eslint/no-unnecessary-condition
|
|
81
|
+
throw new Error('createTestApp() requires options.document when no global document is available.');
|
|
82
|
+
}
|
|
83
|
+
const document = suppliedDocument;
|
|
84
|
+
const ownsContainer = options?.container === undefined;
|
|
85
|
+
const container = options?.container ?? document.createElement('div');
|
|
86
|
+
if (container.ownerDocument !== document) {
|
|
87
|
+
throw new Error('The TestApp container must belong to options.document.');
|
|
88
|
+
}
|
|
89
|
+
if (container.childNodes.length > 0) {
|
|
90
|
+
throw new Error('The TestApp container must be empty before mounting.');
|
|
91
|
+
}
|
|
92
|
+
if (ownsContainer) {
|
|
93
|
+
if (document.body === null) {
|
|
94
|
+
// eslint-disable-line @typescript-eslint/no-unnecessary-condition
|
|
95
|
+
throw new Error('The supplied document must have a body element.');
|
|
96
|
+
}
|
|
97
|
+
document.body.appendChild(container);
|
|
98
|
+
}
|
|
99
|
+
const location = options?.location ?? '/';
|
|
100
|
+
const globalData = options?.globalData ?? {};
|
|
101
|
+
const matchedRouteInfo = {
|
|
102
|
+
key: null,
|
|
103
|
+
params: options?.routeParams ?? {},
|
|
104
|
+
content: null,
|
|
105
|
+
...(options !== undefined && 'routeData' in options ? {
|
|
106
|
+
data: options.routeData
|
|
107
|
+
} : {})
|
|
108
|
+
};
|
|
109
|
+
const scheduler = new UpdateScheduler();
|
|
110
|
+
const runtimeContext = {
|
|
111
|
+
document,
|
|
112
|
+
window: document.defaultView,
|
|
113
|
+
scheduler,
|
|
114
|
+
navigation: false
|
|
115
|
+
};
|
|
116
|
+
const {
|
|
117
|
+
internalStore,
|
|
118
|
+
stores,
|
|
119
|
+
storeSubscriptions
|
|
120
|
+
} = initStores(location, null, globalData, matchedRouteInfo);
|
|
121
|
+
const instanceConfig = {
|
|
122
|
+
prod: false,
|
|
123
|
+
useRootComponent: true,
|
|
124
|
+
clientSideNav: false,
|
|
125
|
+
siteBasePath: '/',
|
|
126
|
+
staticSite: false
|
|
127
|
+
};
|
|
128
|
+
const emptyRoutes = {};
|
|
129
|
+
const instance = new Instance(location, instanceConfig, null, emptyRoutes, emptyRoutes, internalStore, stores, storeSubscriptions, globalData, matchedRouteInfo, runtimeContext);
|
|
130
|
+
try {
|
|
131
|
+
for (const override of options?.stores ?? []) {
|
|
132
|
+
const store = override.registration.getStore(instance.stores);
|
|
133
|
+
await override.initialize(store);
|
|
134
|
+
}
|
|
135
|
+
const props = options?.props ?? {};
|
|
136
|
+
const root = await createTungstenRootComponent(RootComponent, props, options?.routeParams, options?.routeData, instance, container);
|
|
137
|
+
const testApp = new TestAppImplementation(document, container, root.component, instance, scheduler, root, ownsContainer);
|
|
138
|
+
try {
|
|
139
|
+
await testApp.resolved();
|
|
140
|
+
return testApp;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
await testApp.unmount();
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
} catch (error) {
|
|
146
|
+
try {
|
|
147
|
+
instance.disposeRegisteredComponents();
|
|
148
|
+
} catch {
|
|
149
|
+
// Preserve the mount failure.
|
|
150
|
+
}
|
|
151
|
+
scheduler.dispose();
|
|
152
|
+
while (container.firstChild !== null) container.removeChild(container.firstChild);
|
|
153
|
+
if (ownsContainer) container.remove();
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type ScheduledWork = () => void | Promise<void>;
|
|
2
|
+
export declare class UpdateScheduler {
|
|
3
|
+
#private;
|
|
4
|
+
readonly maxPasses: number;
|
|
5
|
+
constructor(maxPasses?: number);
|
|
6
|
+
enqueueUpdate(key: object, run: ScheduledWork, description: string): void;
|
|
7
|
+
enqueueTask(run: ScheduledWork, description: string): void;
|
|
8
|
+
trackWork(run: () => unknown, description: string): void;
|
|
9
|
+
resolved(): Promise<void>;
|
|
10
|
+
private resolvePending;
|
|
11
|
+
private run;
|
|
12
|
+
private recordError;
|
|
13
|
+
private throwRecordedError;
|
|
14
|
+
cancelPending(): void;
|
|
15
|
+
dispose(): void;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=UpdateScheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UpdateScheduler.d.ts","sourceRoot":"","sources":["../../src/update/UpdateScheduler.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAOtD,qBAAa,eAAe;;IAOxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;gBAEd,SAAS,SAAM;IAI3B,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAKzE,WAAW,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAK1D,SAAS,CAAC,GAAG,EAAE,MAAM,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAsBxD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAQX,cAAc;YA6Bd,GAAG;IAQjB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,kBAAkB;IAQ1B,aAAa,IAAI,IAAI;IAKrB,OAAO,IAAI,IAAI;CAMlB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
2
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
3
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
4
|
+
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
|
|
5
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
6
|
+
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
|
|
7
|
+
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
|
|
8
|
+
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
9
|
+
var _updates = /*#__PURE__*/new WeakMap();
|
|
10
|
+
var _tasks = /*#__PURE__*/new WeakMap();
|
|
11
|
+
var _promises = /*#__PURE__*/new WeakMap();
|
|
12
|
+
var _error = /*#__PURE__*/new WeakMap();
|
|
13
|
+
var _disposed = /*#__PURE__*/new WeakMap();
|
|
14
|
+
var _resolving = /*#__PURE__*/new WeakMap();
|
|
15
|
+
export class UpdateScheduler {
|
|
16
|
+
constructor(maxPasses = 100) {
|
|
17
|
+
_classPrivateFieldInitSpec(this, _updates, new Map());
|
|
18
|
+
_classPrivateFieldInitSpec(this, _tasks, []);
|
|
19
|
+
_classPrivateFieldInitSpec(this, _promises, new Set());
|
|
20
|
+
_classPrivateFieldInitSpec(this, _error, void 0);
|
|
21
|
+
_classPrivateFieldInitSpec(this, _disposed, false);
|
|
22
|
+
_classPrivateFieldInitSpec(this, _resolving, void 0);
|
|
23
|
+
_defineProperty(this, "maxPasses", void 0);
|
|
24
|
+
this.maxPasses = maxPasses;
|
|
25
|
+
}
|
|
26
|
+
enqueueUpdate(key, run, description) {
|
|
27
|
+
if (_classPrivateFieldGet(_disposed, this)) return;
|
|
28
|
+
if (!_classPrivateFieldGet(_updates, this).has(key)) _classPrivateFieldGet(_updates, this).set(key, {
|
|
29
|
+
run,
|
|
30
|
+
description
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
enqueueTask(run, description) {
|
|
34
|
+
if (_classPrivateFieldGet(_disposed, this)) return;
|
|
35
|
+
_classPrivateFieldGet(_tasks, this).push({
|
|
36
|
+
run,
|
|
37
|
+
description
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
trackWork(run, description) {
|
|
41
|
+
if (_classPrivateFieldGet(_disposed, this)) return;
|
|
42
|
+
let result;
|
|
43
|
+
try {
|
|
44
|
+
result = run();
|
|
45
|
+
} catch (error) {
|
|
46
|
+
this.recordError(error, description);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (result instanceof Promise || typeof result === 'object' && result !== null && 'then' in result) {
|
|
50
|
+
const promise = Promise.resolve(result).then(() => undefined, error => this.recordError(error, description)).finally(() => {
|
|
51
|
+
_classPrivateFieldGet(_promises, this).delete(promise);
|
|
52
|
+
});
|
|
53
|
+
_classPrivateFieldGet(_promises, this).add(promise);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
resolved() {
|
|
57
|
+
if (_classPrivateFieldGet(_resolving, this) !== undefined) return _classPrivateFieldGet(_resolving, this);
|
|
58
|
+
_classPrivateFieldSet(_resolving, this, this.resolvePending().finally(() => {
|
|
59
|
+
_classPrivateFieldSet(_resolving, this, undefined);
|
|
60
|
+
}));
|
|
61
|
+
return _classPrivateFieldGet(_resolving, this);
|
|
62
|
+
}
|
|
63
|
+
async resolvePending() {
|
|
64
|
+
let passes = 0;
|
|
65
|
+
while (!_classPrivateFieldGet(_disposed, this) && (_classPrivateFieldGet(_tasks, this).length > 0 || _classPrivateFieldGet(_updates, this).size > 0 || _classPrivateFieldGet(_promises, this).size > 0)) {
|
|
66
|
+
passes++;
|
|
67
|
+
if (passes > this.maxPasses) {
|
|
68
|
+
throw new Error(`Tungsten testing scheduler exceeded ${this.maxPasses} passes. ` + 'A component lifecycle may be continuously queueing updates.');
|
|
69
|
+
}
|
|
70
|
+
const tasks = _classPrivateFieldGet(_tasks, this).splice(0);
|
|
71
|
+
for (const task of tasks) await this.run(task);
|
|
72
|
+
const updates = [..._classPrivateFieldGet(_updates, this).values()];
|
|
73
|
+
_classPrivateFieldGet(_updates, this).clear();
|
|
74
|
+
for (const update of updates) await this.run(update);
|
|
75
|
+
if (_classPrivateFieldGet(_promises, this).size > 0) {
|
|
76
|
+
await Promise.all([..._classPrivateFieldGet(_promises, this)]);
|
|
77
|
+
}
|
|
78
|
+
this.throwRecordedError();
|
|
79
|
+
}
|
|
80
|
+
this.throwRecordedError();
|
|
81
|
+
}
|
|
82
|
+
async run(work) {
|
|
83
|
+
try {
|
|
84
|
+
await work.run();
|
|
85
|
+
} catch (error) {
|
|
86
|
+
this.recordError(error, work.description);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
recordError(error, description) {
|
|
90
|
+
if (_classPrivateFieldGet(_error, this) !== undefined) return;
|
|
91
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
92
|
+
_classPrivateFieldSet(_error, this, new Error(`Tungsten ${description} failed: ${message}`, {
|
|
93
|
+
cause: error
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
throwRecordedError() {
|
|
97
|
+
if (_classPrivateFieldGet(_error, this) !== undefined) {
|
|
98
|
+
const error = _classPrivateFieldGet(_error, this);
|
|
99
|
+
_classPrivateFieldSet(_error, this, undefined);
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
cancelPending() {
|
|
104
|
+
_classPrivateFieldGet(_updates, this).clear();
|
|
105
|
+
_classPrivateFieldGet(_tasks, this).length = 0;
|
|
106
|
+
}
|
|
107
|
+
dispose() {
|
|
108
|
+
_classPrivateFieldSet(_disposed, this, true);
|
|
109
|
+
_classPrivateFieldGet(_updates, this).clear();
|
|
110
|
+
_classPrivateFieldGet(_tasks, this).length = 0;
|
|
111
|
+
_classPrivateFieldGet(_promises, this).clear();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -3,13 +3,16 @@ import { ContentNode, ContentNodeHtml, ContentNodeComponentAny } from '../Conten
|
|
|
3
3
|
import { Instance } from '../Instance/Instance.js';
|
|
4
4
|
import { TungstenElement } from '../TungstenElement.js';
|
|
5
5
|
import { AnyComponent } from '../AnyComponent.js';
|
|
6
|
-
import {
|
|
6
|
+
import { $ContentNull } from '../symbols.js';
|
|
7
|
+
import { RenderedContentNode, RenderedContentNodeComponent } from '../RenderedContentNode.js';
|
|
7
8
|
import { UpdateResult } from './UpdateResult.js';
|
|
9
|
+
import type { TungstenBaseComponentType } from '../Components.jsx';
|
|
8
10
|
export type TungstenHTMLElement = HTMLElement & {
|
|
9
11
|
__tungsten_click_handler: (this: HTMLElement, ev: MouseEvent) => any;
|
|
10
12
|
[key: string]: unknown;
|
|
11
13
|
};
|
|
12
14
|
export declare function integrateElementUpdateVdom(element: AnyComponent, newContent: ContentNode): Promise<UpdateResult>;
|
|
15
|
+
export declare function deleteNodeIfRendered(node: $ContentNull | RenderedContentNode): void;
|
|
13
16
|
export declare function processHtmlNode(node: ContentNodeHtml, parentNode: ContentNode): void;
|
|
14
17
|
type CreateTungstenComponentArgs = {
|
|
15
18
|
parent: TungstenElement;
|
|
@@ -18,5 +21,12 @@ type CreateTungstenComponentArgs = {
|
|
|
18
21
|
domPointer: DomPointer;
|
|
19
22
|
};
|
|
20
23
|
export declare function createTungstenComponent({ parent, instance, node, domPointer }: CreateTungstenComponentArgs): Promise<RenderedContentNodeComponent>;
|
|
24
|
+
export type MountedTungstenRoot<ComponentType extends TungstenBaseComponentType<any, any>> = {
|
|
25
|
+
component: InstanceType<ComponentType>;
|
|
26
|
+
openingComment: Comment;
|
|
27
|
+
closingComment: Comment;
|
|
28
|
+
};
|
|
29
|
+
export declare function createTungstenRootComponent<ComponentType extends TungstenBaseComponentType<any, any>>(RootComponent: ComponentType, props: InstanceType<ComponentType>['props'], routeParams: Record<string, string> | undefined, routeData: unknown, instance: Instance, container: HTMLElement): Promise<MountedTungstenRoot<ComponentType>>;
|
|
30
|
+
export declare function deleteTungstenRoot(root: MountedTungstenRoot<TungstenBaseComponentType<any, any>>): void;
|
|
21
31
|
export {};
|
|
22
32
|
//# sourceMappingURL=integrateUpdateVdom.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integrateUpdateVdom.d.ts","sourceRoot":"","sources":["../../src/update/integrateUpdateVdom.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EACH,WAAW,EAAwC,eAAe,EAElE,uBAAuB,EAG1B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAKlD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"integrateUpdateVdom.d.ts","sourceRoot":"","sources":["../../src/update/integrateUpdateVdom.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EACH,WAAW,EAAwC,eAAe,EAElE,uBAAuB,EAG1B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAKlD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGjD,OAAO,EAAE,YAAY,EAAgB,MAAM,eAAe,CAAA;AAE1D,OAAO,EACe,mBAAmB,EAIT,4BAA4B,EAI3D,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAUhD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAGlE,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC5C,wBAAwB,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,KAAK,GAAG,CAAA;IACpE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACzB,CAAA;AAYD,wBAAsB,0BAA0B,CAC5C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,GAC/C,OAAO,CAAC,YAAY,CAAC,CA0GvB;AA+fD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,mBAAmB,QAuC5E;AAgED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,QAkK7E;AA6VD,KAAK,2BAA2B,GAAG;IAC/B,MAAM,EAAE,eAAe,CAAA;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,uBAAuB,CAAC;IAE9B,UAAU,EAAE,UAAU,CAAA;CACzB,CAAA;AACD,wBAAsB,uBAAuB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,2BAA2B,GAC3G,OAAO,CAAC,4BAA4B,CAAC,CAU1C;AAED,MAAM,MAAM,mBAAmB,CAC3B,aAAa,SAAS,yBAAyB,CAAC,GAAG,EAAE,GAAG,CAAC,IACzD;IACA,SAAS,EAAE,YAAY,CAAC,aAAa,CAAC,CAAA;IACtC,cAAc,EAAE,OAAO,CAAA;IACvB,cAAc,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED,wBAAsB,2BAA2B,CAC7C,aAAa,SAAS,yBAAyB,CAAC,GAAG,EAAE,GAAG,CAAC,EAEzD,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,YAAY,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,EAC3C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC/C,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,WAAW,GACvB,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAgD7C;AAED,wBAAgB,kBAAkB,CAC9B,IAAI,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAC/D,IAAI,CAON"}
|