@tellegen/svelte 0.4.6 → 0.5.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/dist/TellegenMap.svelte +21 -26
- package/dist/components/DiagramCanvas.svelte +5 -1
- package/dist/components/McModelQualification.svelte +67 -0
- package/dist/components/McModelQualification.svelte.d.ts +8 -0
- package/dist/components/McNetworkScope.svelte +90 -0
- package/dist/components/McNetworkScope.svelte.d.ts +9 -0
- package/dist/components/McPfSettings.svelte +158 -0
- package/dist/components/McPfSettings.svelte.d.ts +9 -0
- package/dist/components/McResults.svelte +16 -1
- package/dist/components/McResults.svelte.d.ts +1 -0
- package/dist/components/McWorkbench.svelte +2 -0
- package/dist/components/MulticonductorDetails.svelte +25 -6
- package/dist/components.d.ts +3 -0
- package/dist/components.js +3 -0
- package/dist/controller.svelte.d.ts +9 -5
- package/dist/controller.svelte.js +83 -18
- package/dist/diagram/schematic-equipment.d.ts +4 -3
- package/dist/diagram/schematic-equipment.js +13 -1
- package/dist/diagram/snapshot.d.ts +6 -3
- package/dist/diagram/snapshot.js +56 -35
- package/dist/globe-horizon.d.ts +6 -0
- package/dist/globe-horizon.js +41 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/multiconductor.js +38 -4
- package/dist/state.svelte.d.ts +28 -8
- package/dist/state.svelte.js +29 -5
- package/package.json +2 -2
package/dist/multiconductor.js
CHANGED
|
@@ -110,6 +110,43 @@ function withRoutes(view, layer) {
|
|
|
110
110
|
return view;
|
|
111
111
|
const routes = new Map();
|
|
112
112
|
const same = (a, b) => typeof a === 'string' && a.toLowerCase() === b.toLowerCase();
|
|
113
|
+
// Index the edges once by lowercased id and by lowercased directed endpoint
|
|
114
|
+
// pair. A city case carries tens of thousands of routes and edges, so a scan
|
|
115
|
+
// of every edge per feature is quadratic.
|
|
116
|
+
const byId = new Map();
|
|
117
|
+
const byEnds = new Map();
|
|
118
|
+
for (const edge of view.edges) {
|
|
119
|
+
const id = edge.id.toLowerCase();
|
|
120
|
+
const from = edge.from.toLowerCase();
|
|
121
|
+
const to = edge.to.toLowerCase();
|
|
122
|
+
const withId = byId.get(id);
|
|
123
|
+
if (withId)
|
|
124
|
+
withId.push(edge);
|
|
125
|
+
else
|
|
126
|
+
byId.set(id, [edge]);
|
|
127
|
+
let fromEnds = byEnds.get(from);
|
|
128
|
+
if (!fromEnds)
|
|
129
|
+
byEnds.set(from, (fromEnds = new Map()));
|
|
130
|
+
const between = fromEnds.get(to);
|
|
131
|
+
if (between)
|
|
132
|
+
between.push(edge);
|
|
133
|
+
else
|
|
134
|
+
fromEnds.set(to, [edge]);
|
|
135
|
+
}
|
|
136
|
+
const directed = (from, to) => byEnds.get(from)?.get(to) ?? [];
|
|
137
|
+
// The edges `same` would match: by id when the feature names one, otherwise
|
|
138
|
+
// by its endpoints in either direction. A self loop's two directions are one
|
|
139
|
+
// set, so it is not counted twice.
|
|
140
|
+
const matching = (id, from, to) => {
|
|
141
|
+
if (id !== undefined)
|
|
142
|
+
return typeof id === 'string' ? (byId.get(id.toLowerCase()) ?? []) : [];
|
|
143
|
+
if (typeof from !== 'string' || typeof to !== 'string')
|
|
144
|
+
return [];
|
|
145
|
+
const f = from.toLowerCase();
|
|
146
|
+
const t = to.toLowerCase();
|
|
147
|
+
const forward = directed(f, t);
|
|
148
|
+
return f === t ? forward : [...forward, ...directed(t, f)];
|
|
149
|
+
};
|
|
113
150
|
for (const feature of features) {
|
|
114
151
|
const props = feature?.properties;
|
|
115
152
|
const geometry = feature?.geometry;
|
|
@@ -126,10 +163,7 @@ function withRoutes(view, layer) {
|
|
|
126
163
|
const from = props.from ?? props.bus_from;
|
|
127
164
|
const to = props.to ?? props.bus_to;
|
|
128
165
|
const id = props.id ?? props.uid;
|
|
129
|
-
const matches =
|
|
130
|
-
? same(id, edge.id)
|
|
131
|
-
: (same(from, edge.from) && same(to, edge.to)) ||
|
|
132
|
-
(same(from, edge.to) && same(to, edge.from)));
|
|
166
|
+
const matches = matching(id, from, to);
|
|
133
167
|
if (matches.length !== 1)
|
|
134
168
|
continue;
|
|
135
169
|
const edge = matches[0];
|
package/dist/state.svelte.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CaseSummary, DemandDeltas, Network, NetworkBranch, NetworkBus, SensitivityColumn, Solution, SolveIteration } from './api.js';
|
|
2
|
-
import { type StudyView, type BranchRatingDeltas, type BrowserMcPfSession, type CaseFileSummary, type DistGraph, type Formulation, type IngestedDistCase, type McPfCallTiming, type McPfResult, type McPfSummary, type McLoadBranchState, type McLoadPowerEdit, type McStudySnapshot, type SensTarget, type Topology } from '@tellegen/engine';
|
|
2
|
+
import { type StudyView, type BranchRatingDeltas, type BrowserMcPfSession, type CaseFileSummary, type DistGraph, type Formulation, type IngestedDistCase, type McPfCallTiming, type McPfOptions, type McPfResult, type McPfResultTables, type McPfSummary, type McLoadBranchState, type McLoadPowerEdit, type McModuleInput, type McStudySnapshot, type SensTarget, type Topology } from '@tellegen/engine';
|
|
3
3
|
import type { MultiView } from './multiconductor.js';
|
|
4
4
|
import { DiagnosticLog } from './log.svelte.js';
|
|
5
5
|
import { type GraphInputs } from './diagram/graph-inputs.js';
|
|
@@ -181,9 +181,10 @@ export declare class CaseState {
|
|
|
181
181
|
}
|
|
182
182
|
/** A case the solver can run: a server-backed case or a browser-parsed local case. */
|
|
183
183
|
export type SolvableCase = CaseState | LocalCase;
|
|
184
|
-
/** The multiconductor ingest payload without the graph
|
|
185
|
-
* connected load/generation, coordinate
|
|
186
|
-
|
|
184
|
+
/** The multiconductor ingest payload without the graph or the retained
|
|
185
|
+
* input: the summary counts, connected load/generation, coordinate
|
|
186
|
+
* provenance, and diagnostics. */
|
|
187
|
+
export type MultiCaseSummary = Omit<IngestedDistCase, 'graph' | 'input'>;
|
|
187
188
|
/** Geographic coordinates use the map; other positions use the diagram canvas. */
|
|
188
189
|
export type MultiCoordsKind = 'geographic' | 'planar' | 'synthetic';
|
|
189
190
|
/** Where one interactive load edit spent its time, in milliseconds: engine
|
|
@@ -197,7 +198,10 @@ export declare class MulticonductorCase {
|
|
|
197
198
|
readonly id: string;
|
|
198
199
|
readonly label: string;
|
|
199
200
|
readonly fileName: string;
|
|
200
|
-
|
|
201
|
+
/** The electrical input calculations start from: the module the engine
|
|
202
|
+
* keeps from the import, or PowerIO IR text (a saved or re-placed module).
|
|
203
|
+
* A kept module is freed when it is replaced or the case is removed. */
|
|
204
|
+
mcInput: McModuleInput | null;
|
|
201
205
|
geoLayer: string | null;
|
|
202
206
|
geoWarnings: string[];
|
|
203
207
|
/** Summary of the displayed operating point: from the live session after
|
|
@@ -208,6 +212,15 @@ export declare class MulticonductorCase {
|
|
|
208
212
|
mcFullResult: McPfResult | null;
|
|
209
213
|
/** Latency breakdown of the latest load-edit solve. */
|
|
210
214
|
mcTiming: McEditTiming | null;
|
|
215
|
+
/** Explicit selection for the next solve. The graph and module retain every bus. */
|
|
216
|
+
mcEnergizedOnly: boolean;
|
|
217
|
+
/** Successful explicit solve to reveal in Studies; load edits do not advance it. */
|
|
218
|
+
mcCompletedSolveSeq: number;
|
|
219
|
+
/** Detected on import, revalidated when preparing a solve; never removed from the graph. */
|
|
220
|
+
mcExcludedIslands: import('@tellegen/engine').McExcludedIsland[];
|
|
221
|
+
mcPreparedScope: import('@tellegen/engine').McNetworkScope | null;
|
|
222
|
+
/** Selected settings for the next explicit solve; results carry their own effective settings. */
|
|
223
|
+
mcOptions: McPfOptions;
|
|
211
224
|
mcSnapshot: McStudySnapshot | null;
|
|
212
225
|
mcSession: BrowserMcPfSession | null;
|
|
213
226
|
mcLoadBranches: McLoadBranchState[];
|
|
@@ -248,9 +261,10 @@ export declare class MulticonductorCase {
|
|
|
248
261
|
/** Bumped to ask the views to bring the current selection into view again (an issue clicked
|
|
249
262
|
* that is already selected). */
|
|
250
263
|
revealSeq: number;
|
|
251
|
-
/** The full operating point read for whole-network views (overview, schematic)
|
|
252
|
-
* and cleared when a large case's
|
|
253
|
-
|
|
264
|
+
/** The full operating point read for whole-network views (overview, schematic): a stored
|
|
265
|
+
* result, or a live session's as columns. Null until read, and cleared when a large case's
|
|
266
|
+
* operating point changes. */
|
|
267
|
+
overviewResult: McPfResult | McPfResultTables | null;
|
|
254
268
|
overviewLoading: boolean;
|
|
255
269
|
/** The graph's buses and branches as the overview and the diagram read them: rebuilt when the
|
|
256
270
|
* graph is replaced, never after a solve. Both views read this one copy. */
|
|
@@ -270,11 +284,17 @@ export declare class MulticonductorCase {
|
|
|
270
284
|
label: string;
|
|
271
285
|
fileName: string;
|
|
272
286
|
summary: MultiCaseSummary;
|
|
287
|
+
/** The module the engine kept from the import, in place of the
|
|
288
|
+
* summary's `module_json`. */
|
|
289
|
+
input?: McModuleInput | null;
|
|
273
290
|
graph: DistGraph;
|
|
274
291
|
coordsKind: MultiCoordsKind;
|
|
275
292
|
view?: MultiView | null;
|
|
276
293
|
});
|
|
277
294
|
get mcPfReason(): string | null;
|
|
295
|
+
/** Import detects scope; only a solve action opts into the selection. */
|
|
296
|
+
get mcRequiresEnergizedSolve(): boolean;
|
|
297
|
+
get mcSolveLabel(): string;
|
|
278
298
|
get mcPfSupported(): boolean;
|
|
279
299
|
/** Whether the case is placed and ready to render. */
|
|
280
300
|
get placed(): boolean;
|
package/dist/state.svelte.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEFAULT_MC_PF_OPTIONS, summarizeMcExcludedIslands } from '@tellegen/engine';
|
|
1
2
|
import { DEFAULT_FORMULATION } from '@tellegen/engine';
|
|
2
3
|
import { DiagnosticLog, errorEntry } from './log.svelte.js';
|
|
3
4
|
import { graphInputs } from './diagram/graph-inputs.js';
|
|
@@ -127,7 +128,10 @@ export class MulticonductorCase {
|
|
|
127
128
|
id;
|
|
128
129
|
label;
|
|
129
130
|
fileName;
|
|
130
|
-
|
|
131
|
+
/** The electrical input calculations start from: the module the engine
|
|
132
|
+
* keeps from the import, or PowerIO IR text (a saved or re-placed module).
|
|
133
|
+
* A kept module is freed when it is replaced or the case is removed. */
|
|
134
|
+
mcInput = $state.raw(null);
|
|
131
135
|
geoLayer = $state.raw(null);
|
|
132
136
|
geoWarnings = $state.raw([]);
|
|
133
137
|
/** Summary of the displayed operating point: from the live session after
|
|
@@ -138,6 +142,15 @@ export class MulticonductorCase {
|
|
|
138
142
|
mcFullResult = $state.raw(null);
|
|
139
143
|
/** Latency breakdown of the latest load-edit solve. */
|
|
140
144
|
mcTiming = $state.raw(null);
|
|
145
|
+
/** Explicit selection for the next solve. The graph and module retain every bus. */
|
|
146
|
+
mcEnergizedOnly = $state(false);
|
|
147
|
+
/** Successful explicit solve to reveal in Studies; load edits do not advance it. */
|
|
148
|
+
mcCompletedSolveSeq = $state(0);
|
|
149
|
+
/** Detected on import, revalidated when preparing a solve; never removed from the graph. */
|
|
150
|
+
mcExcludedIslands = $state.raw([]);
|
|
151
|
+
mcPreparedScope = $state.raw(null);
|
|
152
|
+
/** Selected settings for the next explicit solve; results carry their own effective settings. */
|
|
153
|
+
mcOptions = $state({ ...DEFAULT_MC_PF_OPTIONS });
|
|
141
154
|
mcSnapshot = $state.raw(null);
|
|
142
155
|
mcSession = $state.raw(null);
|
|
143
156
|
mcLoadBranches = $state.raw([]);
|
|
@@ -172,8 +185,9 @@ export class MulticonductorCase {
|
|
|
172
185
|
/** Bumped to ask the views to bring the current selection into view again (an issue clicked
|
|
173
186
|
* that is already selected). */
|
|
174
187
|
revealSeq = $state(0);
|
|
175
|
-
/** The full operating point read for whole-network views (overview, schematic)
|
|
176
|
-
* and cleared when a large case's
|
|
188
|
+
/** The full operating point read for whole-network views (overview, schematic): a stored
|
|
189
|
+
* result, or a live session's as columns. Null until read, and cleared when a large case's
|
|
190
|
+
* operating point changes. */
|
|
177
191
|
overviewResult = $state.raw(null);
|
|
178
192
|
overviewLoading = $state(false);
|
|
179
193
|
/** The graph's buses and branches as the overview and the diagram read them: rebuilt when the
|
|
@@ -196,14 +210,17 @@ export class MulticonductorCase {
|
|
|
196
210
|
this.label = init.label;
|
|
197
211
|
this.fileName = init.fileName;
|
|
198
212
|
this.summary = init.summary;
|
|
199
|
-
this.
|
|
213
|
+
this.mcInput = init.input ?? init.summary.module_json ?? null;
|
|
214
|
+
this.mcEnergizedOnly = init.summary.mc_energized_only ?? false;
|
|
215
|
+
this.mcExcludedIslands = init.summary.mc_excluded_islands ?? [];
|
|
216
|
+
this.mcPreparedScope = summarizeMcExcludedIslands(this.mcExcludedIslands);
|
|
200
217
|
this.geoLayer = init.summary.geo_layer ?? null;
|
|
201
218
|
this.graph = init.graph;
|
|
202
219
|
this.coordsKind = init.coordsKind;
|
|
203
220
|
this.view = init.view ?? null;
|
|
204
221
|
}
|
|
205
222
|
get mcPfReason() {
|
|
206
|
-
if (!this.
|
|
223
|
+
if (!this.mcInput)
|
|
207
224
|
return 'This case has no retained electrical input';
|
|
208
225
|
if (this.summary?.mc_pf_enabled !== true)
|
|
209
226
|
return 'AC power flow is unavailable in this build';
|
|
@@ -211,6 +228,13 @@ export class MulticonductorCase {
|
|
|
211
228
|
this.summary.mc_pf_unavailable_reason ??
|
|
212
229
|
(this.summary.mc_pf_supported !== true ? 'AC power flow is unavailable for this case' : null));
|
|
213
230
|
}
|
|
231
|
+
/** Import detects scope; only a solve action opts into the selection. */
|
|
232
|
+
get mcRequiresEnergizedSolve() {
|
|
233
|
+
return this.mcExcludedIslands.length > 0;
|
|
234
|
+
}
|
|
235
|
+
get mcSolveLabel() {
|
|
236
|
+
return this.mcRequiresEnergizedSolve ? 'Solve energized network' : 'Run power flow';
|
|
237
|
+
}
|
|
214
238
|
get mcPfSupported() {
|
|
215
239
|
return this.mcPfReason === null;
|
|
216
240
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tellegen/svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Svelte components for tellegen power system maps, local case files, and browser solves.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"svelte",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"pack:dry-run": "npm pack --dry-run --cache ../../node_modules/.cache/npm-pack"
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@tellegen/engine": "^0.
|
|
70
|
+
"@tellegen/engine": "^0.5.0"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
73
|
"@deck.gl/core": "^9.4.0",
|