@tellegen/svelte 0.2.0 → 0.3.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/README.md +36 -5
- package/dist/TellegenMap.svelte +325 -163
- package/dist/TellegenProvider.svelte +4 -0
- package/dist/TellegenShell.svelte +19 -13
- package/dist/api.d.ts +8 -1
- package/dist/api.js +6 -2
- package/dist/colors.d.ts +7 -7
- package/dist/colors.js +13 -13
- package/dist/components/AppHeader.svelte +23 -11
- package/dist/components/BindingLines.svelte +3 -6
- package/dist/components/BusPicker.svelte +8 -2
- package/dist/components/ControlPanel.svelte +106 -343
- package/dist/components/DemandSlider.svelte +21 -23
- package/dist/components/DiagramCanvas.svelte +486 -0
- package/dist/components/DiagramCanvas.svelte.d.ts +13 -0
- package/dist/components/DisplayControls.svelte +4 -2
- package/dist/components/FormulationSelector.svelte +8 -3
- package/dist/components/LocalCaseDetails.svelte +55 -45
- package/dist/components/McResults.svelte +365 -0
- package/dist/components/McResults.svelte.d.ts +11 -0
- package/dist/components/ModelDetails.svelte +230 -0
- package/dist/components/ModelDetails.svelte.d.ts +7 -0
- package/dist/components/MulticonductorDetails.svelte +227 -78
- package/dist/components/NetworkStats.svelte +20 -18
- package/dist/components/NotificationCenter.svelte +243 -0
- package/dist/components/NotificationCenter.svelte.d.ts +3 -0
- package/dist/components/PanelCard.svelte +319 -0
- package/dist/components/PanelCard.svelte.d.ts +9 -0
- package/dist/components/PanelFrame.svelte +46 -0
- package/dist/components/PanelFrame.svelte.d.ts +16 -0
- package/dist/components/PanelHost.svelte +212 -0
- package/dist/components/PanelHost.svelte.d.ts +3 -0
- package/dist/components/PowerFlowDetails.svelte +99 -0
- package/dist/components/PowerFlowDetails.svelte.d.ts +3 -0
- package/dist/components/RatingSlider.svelte +5 -9
- package/dist/components/SavedNetworkDetails.svelte +214 -0
- package/dist/components/SavedNetworkDetails.svelte.d.ts +3 -0
- package/dist/components/SensitivityReadout.svelte +24 -16
- package/dist/components/SolveCard.svelte +46 -49
- package/dist/components/TopMovers.svelte +8 -3
- package/dist/components/TopMovers.svelte.d.ts +2 -17
- package/dist/components.d.ts +2 -0
- package/dist/components.js +2 -0
- package/dist/controller.svelte.d.ts +54 -33
- package/dist/controller.svelte.js +927 -233
- package/dist/diagram-labels.d.ts +9 -0
- package/dist/diagram-labels.js +40 -0
- package/dist/display.d.ts +3 -7
- package/dist/display.js +31 -27
- package/dist/format.js +5 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +7 -2
- package/dist/map.d.ts +1 -1
- package/dist/map.js +1 -1
- package/dist/multiconductor.d.ts +11 -2
- package/dist/multiconductor.js +107 -14
- package/dist/notices.svelte.d.ts +29 -0
- package/dist/notices.svelte.js +82 -0
- package/dist/panels.svelte.d.ts +65 -0
- package/dist/panels.svelte.js +215 -0
- package/dist/state.svelte.d.ts +90 -23
- package/dist/state.svelte.js +94 -20
- package/dist/synthetic-layout.js +1 -0
- package/package.json +22 -9
- package/dist/study-package.d.ts +0 -8
- package/dist/study-package.js +0 -17
package/dist/state.svelte.js
CHANGED
|
@@ -12,16 +12,19 @@ export class LocalCase {
|
|
|
12
12
|
id;
|
|
13
13
|
label;
|
|
14
14
|
fileName;
|
|
15
|
+
declaredFormulation;
|
|
15
16
|
/** Case stats; null for a .pwd display only entry. */
|
|
16
17
|
summary = $state.raw(null);
|
|
17
|
-
/**
|
|
18
|
-
|
|
18
|
+
/** Generation 2 PowerIO IR used for display edits and solver studies. */
|
|
19
|
+
studyInputJson = $state.raw(undefined);
|
|
19
20
|
/** Topology for synthetic placement when the file has no coordinates. */
|
|
20
21
|
topology = $state.raw(undefined);
|
|
21
22
|
coordsKind = $state.raw(undefined);
|
|
22
23
|
/** Map geometry when the file carried or received coordinates. */
|
|
23
24
|
view = $state.raw(null);
|
|
24
25
|
syntheticCenter = $state.raw(undefined);
|
|
26
|
+
diagram = $state.raw(null);
|
|
27
|
+
displayMode = $state('geographic');
|
|
25
28
|
geoSource = $state.raw(undefined);
|
|
26
29
|
geoWarnings = $state.raw(undefined);
|
|
27
30
|
network = $state.raw(null);
|
|
@@ -31,8 +34,7 @@ export class LocalCase {
|
|
|
31
34
|
deltas = $state.raw({});
|
|
32
35
|
/** Committed branch rating deltas (MW from base, keyed by branch). */
|
|
33
36
|
ratings = $state.raw({});
|
|
34
|
-
/** The
|
|
35
|
-
* full AC OPF, or the SOCWR relaxation. Changing it rebuilds the Study. */
|
|
37
|
+
/** The selected calculation. Changing it rebuilds the numerical Study. */
|
|
36
38
|
formulation = $state(DEFAULT_FORMULATION);
|
|
37
39
|
iterations = $state.raw([]);
|
|
38
40
|
solving = $state(false);
|
|
@@ -41,6 +43,8 @@ export class LocalCase {
|
|
|
41
43
|
solveFallbackReason = $state(null);
|
|
42
44
|
/** Monotone token: only the latest solve may write this case. */
|
|
43
45
|
solveSeq = 0;
|
|
46
|
+
/** Monotone generation for external optimistic concurrency. */
|
|
47
|
+
revisionGeneration = $state(0);
|
|
44
48
|
/** Monotone token: only the latest sensitivity request may write this case. */
|
|
45
49
|
sensitivitySeq = 0;
|
|
46
50
|
predictedObjective = $state(null);
|
|
@@ -50,8 +54,10 @@ export class LocalCase {
|
|
|
50
54
|
this.id = init.id;
|
|
51
55
|
this.label = init.label;
|
|
52
56
|
this.fileName = init.fileName;
|
|
57
|
+
this.formulation = init.formulation ?? DEFAULT_FORMULATION;
|
|
58
|
+
this.declaredFormulation = init.declaredFormulation;
|
|
53
59
|
this.summary = init.summary ?? null;
|
|
54
|
-
this.
|
|
60
|
+
this.studyInputJson = init.studyInputJson;
|
|
55
61
|
this.topology = init.topology;
|
|
56
62
|
this.coordsKind = init.coordsKind;
|
|
57
63
|
this.view = init.view ?? null;
|
|
@@ -66,9 +72,10 @@ export class LocalCase {
|
|
|
66
72
|
export class CaseState {
|
|
67
73
|
id;
|
|
68
74
|
name;
|
|
75
|
+
unavailableReason;
|
|
69
76
|
network = $state.raw(null);
|
|
70
|
-
/**
|
|
71
|
-
|
|
77
|
+
/** Retained PowerIO module for the browser solver; fetched lazily. */
|
|
78
|
+
studyInputJson = $state.raw(null);
|
|
72
79
|
/** Boot solution at base demand; never changes. */
|
|
73
80
|
baseSolution = $state.raw(null);
|
|
74
81
|
/** Exact solution at the current committed perturbation. */
|
|
@@ -88,6 +95,8 @@ export class CaseState {
|
|
|
88
95
|
solveFallbackReason = $state(null);
|
|
89
96
|
/** Monotone token: only the latest solve may write this case. */
|
|
90
97
|
solveSeq = 0;
|
|
98
|
+
/** Monotone generation for external optimistic concurrency. */
|
|
99
|
+
revisionGeneration = $state(0);
|
|
91
100
|
/** Monotone token: only the latest sensitivity request may write this case. */
|
|
92
101
|
sensitivitySeq = 0;
|
|
93
102
|
/** Closer for this case's in-flight server solve stream, if any. Owned per
|
|
@@ -99,26 +108,41 @@ export class CaseState {
|
|
|
99
108
|
constructor(summary) {
|
|
100
109
|
this.id = summary.id;
|
|
101
110
|
this.name = summary.name;
|
|
111
|
+
this.unavailableReason = summary.unavailable_reason ?? null;
|
|
102
112
|
}
|
|
103
113
|
get perturbed() {
|
|
104
114
|
return hasPerturbation(this.deltas) || hasPerturbation(this.ratings);
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
|
-
/** A
|
|
108
|
-
* formulation, no sliders, no Study. It carries the bus/terminal graph, its
|
|
109
|
-
* placed map view, and the selected bus whose terminal detail expands. Fields
|
|
110
|
-
* are reactive like the solvable cases so the panel and map track them. */
|
|
117
|
+
/** A conductor-resolved case with retained electrical inputs and terminal results. */
|
|
111
118
|
export class MulticonductorCase {
|
|
112
119
|
id;
|
|
113
120
|
label;
|
|
114
121
|
fileName;
|
|
122
|
+
moduleJson = $state.raw(null);
|
|
123
|
+
geoLayer = $state.raw(null);
|
|
124
|
+
geoWarnings = $state.raw([]);
|
|
125
|
+
result = $state.raw(null);
|
|
126
|
+
mcSnapshot = $state.raw(null);
|
|
127
|
+
mcSession = $state.raw(null);
|
|
128
|
+
mcLoadBranches = $state.raw([]);
|
|
129
|
+
mcLoadEdits = $state.raw([]);
|
|
130
|
+
mcEditRevision = 0;
|
|
131
|
+
mcEditRunning = false;
|
|
132
|
+
mcEditTimer = null;
|
|
133
|
+
mcSavedAt = $state(null);
|
|
134
|
+
solving = $state(false);
|
|
135
|
+
solveMs = $state(null);
|
|
136
|
+
solveSeq = 0;
|
|
137
|
+
revisionGeneration = $state(0);
|
|
138
|
+
solveAbort = null;
|
|
115
139
|
/** Summary counts and coordinate provenance from the parse. */
|
|
116
140
|
summary = $state.raw(null);
|
|
117
141
|
/** The render-ready bus/terminal graph. */
|
|
118
142
|
graph = $state.raw(null);
|
|
119
143
|
/** Placement kind resolved at ingest from the case's coordinate space. */
|
|
120
144
|
coordsKind = $state.raw('synthetic');
|
|
121
|
-
/** The
|
|
145
|
+
/** The map or diagram positions. */
|
|
122
146
|
view = $state.raw(null);
|
|
123
147
|
syntheticCenter = $state.raw(undefined);
|
|
124
148
|
/** The selected bus id, whose terminal stack and incident conductors expand;
|
|
@@ -132,10 +156,24 @@ export class MulticonductorCase {
|
|
|
132
156
|
this.label = init.label;
|
|
133
157
|
this.fileName = init.fileName;
|
|
134
158
|
this.summary = init.summary;
|
|
159
|
+
this.moduleJson = init.summary.module_json ?? null;
|
|
160
|
+
this.geoLayer = init.summary.geo_layer ?? null;
|
|
135
161
|
this.graph = init.graph;
|
|
136
162
|
this.coordsKind = init.coordsKind;
|
|
137
163
|
this.view = init.view ?? null;
|
|
138
164
|
}
|
|
165
|
+
get mcPfReason() {
|
|
166
|
+
if (!this.moduleJson)
|
|
167
|
+
return 'This case has no retained electrical input';
|
|
168
|
+
if (this.summary?.mc_pf_enabled !== true)
|
|
169
|
+
return 'AC power flow is unavailable in this build';
|
|
170
|
+
return (this.summary.mc_pf_reason ??
|
|
171
|
+
this.summary.mc_pf_unavailable_reason ??
|
|
172
|
+
(this.summary.mc_pf_supported !== true ? 'AC power flow is unavailable for this case' : null));
|
|
173
|
+
}
|
|
174
|
+
get mcPfSupported() {
|
|
175
|
+
return this.mcPfReason === null;
|
|
176
|
+
}
|
|
139
177
|
/** Whether the case is placed and ready to render. */
|
|
140
178
|
get placed() {
|
|
141
179
|
return this.view !== null;
|
|
@@ -154,6 +192,40 @@ export class MulticonductorCase {
|
|
|
154
192
|
}
|
|
155
193
|
}
|
|
156
194
|
export class AppState {
|
|
195
|
+
camera = $state.raw(null);
|
|
196
|
+
cameraRequest = $state.raw(null);
|
|
197
|
+
cameraSeq = $state(0);
|
|
198
|
+
diagramCamera = $state.raw(null);
|
|
199
|
+
diagramCameraRequest = $state.raw(null);
|
|
200
|
+
diagramCameraSeq = $state(0);
|
|
201
|
+
requestDiagramCamera(caseId, snapshot) {
|
|
202
|
+
if (!Array.isArray(snapshot.center) ||
|
|
203
|
+
snapshot.center.length !== 2 ||
|
|
204
|
+
![...snapshot.center, snapshot.scale].every(Number.isFinite) ||
|
|
205
|
+
snapshot.scale <= 0) {
|
|
206
|
+
throw new Error('Invalid saved drawing view');
|
|
207
|
+
}
|
|
208
|
+
this.settleFrame();
|
|
209
|
+
this.diagramCameraRequest = { caseId, center: [...snapshot.center], scale: snapshot.scale };
|
|
210
|
+
this.diagramCameraSeq++;
|
|
211
|
+
}
|
|
212
|
+
requestCamera(snapshot) {
|
|
213
|
+
if (!Array.isArray(snapshot.center) ||
|
|
214
|
+
snapshot.center.length !== 2 ||
|
|
215
|
+
![...snapshot.center, snapshot.zoom, snapshot.bearing, snapshot.pitch].every(Number.isFinite) ||
|
|
216
|
+
Math.abs(snapshot.center[1]) > 90 ||
|
|
217
|
+
snapshot.zoom < 0 ||
|
|
218
|
+
snapshot.zoom > 24 ||
|
|
219
|
+
snapshot.pitch < 0 ||
|
|
220
|
+
snapshot.pitch > 85) {
|
|
221
|
+
throw new Error('Invalid saved camera position');
|
|
222
|
+
}
|
|
223
|
+
this.settleFrame();
|
|
224
|
+
this.cameraRequest = { ...snapshot, center: [...snapshot.center] };
|
|
225
|
+
this.cameraSeq++;
|
|
226
|
+
}
|
|
227
|
+
/** Saved Study inspection is independent of the editable case and its solution. */
|
|
228
|
+
studyView = $state.raw(null);
|
|
157
229
|
cases = $state.raw([]);
|
|
158
230
|
activeCaseId = $state(null);
|
|
159
231
|
/** Selected bus in the active case. */
|
|
@@ -164,18 +236,18 @@ export class AppState {
|
|
|
164
236
|
previewDeltaMw = $state(null);
|
|
165
237
|
/** Live rating slider value (MW from base) before commit; null when idle. */
|
|
166
238
|
previewRatingMw = $state(null);
|
|
167
|
-
/** True while the demand control should keep the map in
|
|
239
|
+
/** True while the demand control should keep the map in nodal value preview mode. */
|
|
168
240
|
previewActive = $state(false);
|
|
169
|
-
/** Engine first
|
|
170
|
-
* ($/MWh) per bus at the previewed edit, scoped to the case and selection
|
|
241
|
+
/** Engine first order nodal value preview for the live drag, scoped to the case and selection
|
|
171
242
|
* target (bus or branch) it was computed for. Set by the Study path; null when
|
|
172
243
|
* no Study preview applies (the map then falls back to the JS
|
|
173
244
|
* sensitivity-times-step preview). Reassigned wholesale, so $state.raw. */
|
|
174
|
-
|
|
245
|
+
previewPrices = $state.raw(null);
|
|
175
246
|
demandRangeMode = $state('local');
|
|
176
|
-
displayMode = $state('
|
|
247
|
+
displayMode = $state('price');
|
|
177
248
|
sensitivityLoading = $state(false);
|
|
178
249
|
#error = $state(null);
|
|
250
|
+
errorRevision = $state(0);
|
|
179
251
|
/** Re-runs the operation behind the current `error`, when one applies. Every
|
|
180
252
|
* write to `error` clears it, so a retry op can never outlive its message. */
|
|
181
253
|
errorRetry = $state.raw(null);
|
|
@@ -184,6 +256,8 @@ export class AppState {
|
|
|
184
256
|
}
|
|
185
257
|
set error(message) {
|
|
186
258
|
this.#error = message;
|
|
259
|
+
if (message)
|
|
260
|
+
this.errorRevision++;
|
|
187
261
|
this.errorRetry = null;
|
|
188
262
|
}
|
|
189
263
|
/** Case files parsed in the browser via the powerio wasm module. */
|
|
@@ -191,7 +265,7 @@ export class AppState {
|
|
|
191
265
|
/** Local case the panel shows; clicking a bundled case or a bus clears it. */
|
|
192
266
|
activeLocalId = $state(null);
|
|
193
267
|
placingLocalId = $state(null);
|
|
194
|
-
/** Multiconductor
|
|
268
|
+
/** Multiconductor cases with retained inputs and AC power flow results. */
|
|
195
269
|
multiCases = $state.raw([]);
|
|
196
270
|
/** Multiconductor case the panel shows; mutually exclusive with the solvable
|
|
197
271
|
* active ids. */
|
|
@@ -273,7 +347,7 @@ export class AppState {
|
|
|
273
347
|
this.previewDeltaMw = null;
|
|
274
348
|
this.previewRatingMw = null;
|
|
275
349
|
this.previewActive = false;
|
|
276
|
-
this.
|
|
350
|
+
this.previewPrices = null;
|
|
277
351
|
this.demandRangeMode = 'local';
|
|
278
352
|
this.sensitivityLoading = false;
|
|
279
353
|
return this.activateFallback();
|
|
@@ -295,7 +369,7 @@ export class AppState {
|
|
|
295
369
|
// else a remaining local case that can render (a view or substations) or is
|
|
296
370
|
// awaiting placement, else the first remaining local. Frames whatever it picks.
|
|
297
371
|
activateFallback() {
|
|
298
|
-
this.activeCaseId = this.cases
|
|
372
|
+
this.activeCaseId = this.cases.find((c) => !c.unavailableReason)?.id ?? null;
|
|
299
373
|
if (this.activeCaseId) {
|
|
300
374
|
this.requestFrame(this.activeCaseId);
|
|
301
375
|
return { kind: 'backend', id: this.activeCaseId };
|
package/dist/synthetic-layout.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tellegen/svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Svelte components for tellegen power system maps, local case files, and browser solves.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"svelte",
|
|
7
|
+
"sveltekit",
|
|
8
|
+
"power-flow",
|
|
9
|
+
"optimal-power-flow",
|
|
10
|
+
"power-systems",
|
|
11
|
+
"map",
|
|
12
|
+
"maplibre",
|
|
13
|
+
"deck.gl",
|
|
14
|
+
"webassembly",
|
|
15
|
+
"visualization",
|
|
16
|
+
"grid"
|
|
17
|
+
],
|
|
5
18
|
"license": "MIT",
|
|
6
19
|
"type": "module",
|
|
7
20
|
"repository": {
|
|
@@ -49,11 +62,11 @@
|
|
|
49
62
|
"pack:dry-run": "npm pack --dry-run --cache ../../node_modules/.cache/npm-pack"
|
|
50
63
|
},
|
|
51
64
|
"dependencies": {
|
|
52
|
-
"@deck.gl/core": "^9.
|
|
53
|
-
"@deck.gl/layers": "^9.
|
|
54
|
-
"@deck.gl/
|
|
55
|
-
"@tellegen/engine": "^0.
|
|
56
|
-
"maplibre-gl": "^
|
|
65
|
+
"@deck.gl/core": "^9.4.0",
|
|
66
|
+
"@deck.gl/layers": "^9.4.0",
|
|
67
|
+
"@deck.gl/maplibre": "^9.4.0",
|
|
68
|
+
"@tellegen/engine": "^0.3.0",
|
|
69
|
+
"maplibre-gl": "^6.10.0"
|
|
57
70
|
},
|
|
58
71
|
"peerDependencies": {
|
|
59
72
|
"svelte": ">=5.30 <6"
|
|
@@ -61,10 +74,10 @@
|
|
|
61
74
|
"devDependencies": {
|
|
62
75
|
"@sveltejs/package": "^2.3.0",
|
|
63
76
|
"@sveltejs/vite-plugin-svelte": "^7.3.0",
|
|
64
|
-
"svelte": "^5.
|
|
77
|
+
"svelte": "^5.57.0",
|
|
65
78
|
"svelte-check": "^4.7.6",
|
|
66
79
|
"typescript": "^6.0.3",
|
|
67
|
-
"vite": "^8.2.
|
|
68
|
-
"vitest": "^
|
|
80
|
+
"vite": "^8.2.2",
|
|
81
|
+
"vitest": "^5.0.0"
|
|
69
82
|
}
|
|
70
83
|
}
|
package/dist/study-package.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/** Client-side helper for saved study packages (`.pio.json`). The engine owns
|
|
2
|
-
* parsing, restoring, and exporting; classification of a dropped file lives in
|
|
3
|
-
* `drop-classify.ts` (the single owner). This module covers the one remaining
|
|
4
|
-
* frontend decision around a package: which commit an export targets. */
|
|
5
|
-
/** The commit index for a saved package's current committed state: its last study
|
|
6
|
-
* commit, or 0 when it carries none (export then writes the base network). Tolerant of
|
|
7
|
-
* malformed input, returning 0 rather than throwing. */
|
|
8
|
-
export declare function studyCommitIndex(packageJson: string): number;
|
package/dist/study-package.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/** Client-side helper for saved study packages (`.pio.json`). The engine owns
|
|
2
|
-
* parsing, restoring, and exporting; classification of a dropped file lives in
|
|
3
|
-
* `drop-classify.ts` (the single owner). This module covers the one remaining
|
|
4
|
-
* frontend decision around a package: which commit an export targets. */
|
|
5
|
-
/** The commit index for a saved package's current committed state: its last study
|
|
6
|
-
* commit, or 0 when it carries none (export then writes the base network). Tolerant of
|
|
7
|
-
* malformed input, returning 0 rather than throwing. */
|
|
8
|
-
export function studyCommitIndex(packageJson) {
|
|
9
|
-
try {
|
|
10
|
-
const commits = JSON.parse(packageJson).study?.commits
|
|
11
|
-
?.length;
|
|
12
|
-
return Math.max(0, (commits ?? 0) - 1);
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return 0;
|
|
16
|
-
}
|
|
17
|
-
}
|