@snaptrude/plugin-core 0.9.16 → 0.9.18-networks-20261016.1
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/AGENTS.md +231 -231
- package/CHANGELOG.md +408 -402
- package/CLAUDE.md +11 -11
- package/dist/api/analysis/daylight.d.ts +5 -5
- package/dist/api/analysis/solar.d.ts +2 -2
- package/dist/api/core/camera/index.d.ts +29 -0
- package/dist/api/core/camera/index.d.ts.map +1 -1
- package/dist/api/core/geom/create/index.d.ts +7 -1
- package/dist/api/core/geom/create/index.d.ts.map +1 -1
- package/dist/api/core/geom/update/contour.d.ts +8 -2
- package/dist/api/core/geom/update/contour.d.ts.map +1 -1
- package/dist/api/core/zoom/index.d.ts +13 -0
- package/dist/api/core/zoom/index.d.ts.map +1 -1
- package/dist/api/design/bim.d.ts +209 -0
- package/dist/api/design/bim.d.ts.map +1 -0
- package/dist/api/design/boolean/index.d.ts +2 -0
- package/dist/api/design/boolean/index.d.ts.map +1 -1
- package/dist/api/design/catalog.d.ts +320 -0
- package/dist/api/design/catalog.d.ts.map +1 -0
- package/dist/api/design/create/bulk-items.d.ts +65 -25
- package/dist/api/design/create/bulk-items.d.ts.map +1 -1
- package/dist/api/design/create/index.d.ts +272 -99
- package/dist/api/design/create/index.d.ts.map +1 -1
- package/dist/api/design/create/opening-fields.d.ts +13 -12
- package/dist/api/design/create/opening-fields.d.ts.map +1 -1
- package/dist/api/design/delete/index.d.ts +1 -0
- package/dist/api/design/delete/index.d.ts.map +1 -1
- package/dist/api/design/doors/index.d.ts +18 -24
- package/dist/api/design/doors/index.d.ts.map +1 -1
- package/dist/api/design/family.d.ts +797 -27
- package/dist/api/design/family.d.ts.map +1 -1
- package/dist/api/design/index.d.ts +16 -0
- package/dist/api/design/index.d.ts.map +1 -1
- package/dist/api/design/networks.d.ts +1763 -0
- package/dist/api/design/networks.d.ts.map +1 -0
- package/dist/api/design/query/index.d.ts +42 -32
- package/dist/api/design/query/index.d.ts.map +1 -1
- package/dist/api/design/selection/index.d.ts +10 -10
- package/dist/api/design/types/index.d.ts +40 -24
- package/dist/api/design/types/index.d.ts.map +1 -1
- package/dist/api/design/update/index.d.ts +43 -3
- package/dist/api/design/update/index.d.ts.map +1 -1
- package/dist/api/design/windows/index.d.ts +8 -8
- package/dist/api/design/windows/index.d.ts.map +1 -1
- package/dist/api/presentation/aiInspiration.d.ts +10 -10
- package/dist/api/presentation/annotate.d.ts +38 -22
- package/dist/api/presentation/annotate.d.ts.map +1 -1
- package/dist/api/presentation/drawingContract.d.ts +32 -0
- package/dist/api/presentation/drawingContract.d.ts.map +1 -0
- package/dist/api/presentation/drawings.d.ts +3523 -0
- package/dist/api/presentation/drawings.d.ts.map +1 -0
- package/dist/api/presentation/export.d.ts +23 -5
- package/dist/api/presentation/export.d.ts.map +1 -1
- package/dist/api/presentation/index.d.ts +41 -12
- package/dist/api/presentation/index.d.ts.map +1 -1
- package/dist/api/presentation/placedViews.d.ts +106 -6
- package/dist/api/presentation/placedViews.d.ts.map +1 -1
- package/dist/api/presentation/sections.d.ts +461 -0
- package/dist/api/presentation/sections.d.ts.map +1 -0
- package/dist/api/presentation/shapes.d.ts +2 -2
- package/dist/api/presentation/sheets.d.ts +175 -19
- package/dist/api/presentation/sheets.d.ts.map +1 -1
- package/dist/api/presentation/viewPresets.d.ts +222 -0
- package/dist/api/presentation/viewPresets.d.ts.map +1 -0
- package/dist/api/presentation/views.d.ts +103 -5
- package/dist/api/presentation/views.d.ts.map +1 -1
- package/dist/api/presentation/walkthroughs.d.ts +6 -6
- package/dist/errors/codes.d.ts +3 -1
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/index.cjs +3788 -2328
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3650 -2328
- package/dist/index.js.map +1 -1
- package/package.json +42 -42
- package/scripts/check-dist-fresh.mjs +22 -22
- package/scripts/generate-manifest.mjs +243 -238
- package/scripts/generate-manifest.test.mjs +303 -303
- package/src/api/analysis/daylight.ts +470 -470
- package/src/api/analysis/heatmaps.ts +683 -683
- package/src/api/analysis/illuminance.ts +155 -155
- package/src/api/analysis/index.ts +61 -61
- package/src/api/analysis/shadows.ts +183 -183
- package/src/api/analysis/solar.ts +237 -237
- package/src/api/analysis/sunlightHours.ts +211 -211
- package/src/api/analysis/sunpath.ts +83 -83
- package/src/api/analysis/weather.ts +179 -179
- package/src/api/core/buildings.ts +485 -485
- package/src/api/core/camera/index.ts +696 -667
- package/src/api/core/comment/index.ts +376 -376
- package/src/api/core/geom/create/index.ts +2139 -2133
- package/src/api/core/geom/delete/index.ts +84 -84
- package/src/api/core/geom/index.ts +35 -35
- package/src/api/core/geom/query/arc.ts +169 -169
- package/src/api/core/geom/query/brep.ts +621 -621
- package/src/api/core/geom/query/circle.ts +404 -404
- package/src/api/core/geom/query/contour.ts +540 -540
- package/src/api/core/geom/query/curve.ts +1102 -1102
- package/src/api/core/geom/query/edge.ts +130 -130
- package/src/api/core/geom/query/face.ts +508 -508
- package/src/api/core/geom/query/halfedge.ts +210 -210
- package/src/api/core/geom/query/index.ts +63 -63
- package/src/api/core/geom/query/profile.ts +473 -473
- package/src/api/core/geom/query/vertex.ts +205 -205
- package/src/api/core/geom/update/contour.ts +323 -317
- package/src/api/core/geom/update/curve.ts +209 -209
- package/src/api/core/geom/update/index.ts +29 -29
- package/src/api/core/geom/update/profile.ts +379 -379
- package/src/api/core/groups.ts +521 -521
- package/src/api/core/handles/index.ts +234 -234
- package/src/api/core/history/index.ts +84 -84
- package/src/api/core/index.ts +99 -99
- package/src/api/core/io/export/index.ts +126 -126
- package/src/api/core/io/import/index.ts +504 -504
- package/src/api/core/io/index.ts +42 -42
- package/src/api/core/io/job/index.ts +140 -140
- package/src/api/core/io/query/index.ts +71 -71
- package/src/api/core/io/terrain/index.ts +360 -360
- package/src/api/core/io/underlay/index.ts +705 -705
- package/src/api/core/layers.ts +540 -540
- package/src/api/core/math/index.ts +20 -20
- package/src/api/core/math/quat.ts +172 -172
- package/src/api/core/math/vec3.ts +179 -179
- package/src/api/core/mode/index.ts +108 -108
- package/src/api/core/project/index.ts +479 -479
- package/src/api/core/proposals/index.ts +570 -570
- package/src/api/core/storeys/index.ts +308 -308
- package/src/api/core/storeys/layers.ts +339 -339
- package/src/api/core/tags.ts +911 -911
- package/src/api/core/units/index.ts +164 -164
- package/src/api/core/user.ts +46 -46
- package/src/api/core/zoom/index.ts +64 -51
- package/src/api/design/bim.ts +121 -0
- package/src/api/design/boolean/index.ts +181 -179
- package/src/api/design/catalog.ts +203 -0
- package/src/api/design/create/bulk-items.ts +294 -254
- package/src/api/design/create/grids.ts +137 -137
- package/src/api/design/create/index.ts +2148 -1980
- package/src/api/design/create/opening-fields.ts +40 -37
- package/src/api/design/delete/index.ts +75 -74
- package/src/api/design/dimensions.ts +453 -453
- package/src/api/design/doors/index.ts +516 -500
- package/src/api/design/edit/index.ts +54 -54
- package/src/api/design/erase/index.ts +151 -151
- package/src/api/design/family.ts +1334 -704
- package/src/api/design/furniture/index.ts +319 -319
- package/src/api/design/grids.ts +237 -237
- package/src/api/design/index.ts +304 -274
- package/src/api/design/lock.ts +69 -69
- package/src/api/design/materials/index.ts +608 -608
- package/src/api/design/networks.ts +667 -0
- package/src/api/design/query/geometry/index.ts +319 -319
- package/src/api/design/query/grids.ts +197 -197
- package/src/api/design/query/index.ts +1236 -1226
- package/src/api/design/query/referenceLines.ts +52 -52
- package/src/api/design/query/spaces.ts +275 -275
- package/src/api/design/selection/index.ts +273 -273
- package/src/api/design/shared.ts +40 -40
- package/src/api/design/transform/index.ts +254 -254
- package/src/api/design/types/index.ts +163 -156
- package/src/api/design/update/index.ts +1024 -983
- package/src/api/design/visibility.ts +143 -143
- package/src/api/design/windows/index.ts +351 -333
- package/src/api/entity/buildableEnvelope.ts +322 -322
- package/src/api/entity/index.ts +30 -30
- package/src/api/entity/referenceLine.ts +235 -235
- package/src/api/entity/space.ts +612 -612
- package/src/api/entity/story.ts +517 -517
- package/src/api/index.ts +47 -47
- package/src/api/presentation/aiInspiration.ts +1116 -1116
- package/src/api/presentation/annotate.ts +417 -385
- package/src/api/presentation/camera.ts +289 -289
- package/src/api/presentation/diagrams.ts +194 -194
- package/src/api/presentation/drawingContract.ts +70 -0
- package/src/api/presentation/drawings.ts +1179 -0
- package/src/api/presentation/export.ts +134 -108
- package/src/api/presentation/import.ts +159 -159
- package/src/api/presentation/index.ts +160 -126
- package/src/api/presentation/placedViews.ts +1211 -1120
- package/src/api/presentation/sections.ts +420 -0
- package/src/api/presentation/shapes.ts +274 -274
- package/src/api/presentation/sheets.ts +746 -585
- package/src/api/presentation/slideshow.ts +134 -134
- package/src/api/presentation/tables.ts +84 -84
- package/src/api/presentation/viewPresets.ts +241 -0
- package/src/api/presentation/views.ts +713 -673
- package/src/api/presentation/walkthroughs.ts +1201 -1201
- package/src/api/program/adjacency.ts +164 -164
- package/src/api/program/areas.ts +408 -408
- package/src/api/program/classification.ts +138 -138
- package/src/api/program/cores.ts +83 -83
- package/src/api/program/departments.ts +517 -517
- package/src/api/program/index.ts +73 -73
- package/src/api/program/labels.ts +332 -332
- package/src/api/program/layout.ts +422 -422
- package/src/api/program/metadata.ts +364 -364
- package/src/api/program/metrics.ts +120 -120
- package/src/api/program/site.ts +748 -748
- package/src/api/program/spreadsheet.ts +2698 -2698
- package/src/api/workspace/index.ts +612 -612
- package/src/errors/codes.ts +143 -136
- package/src/errors/envelope.ts +75 -75
- package/src/errors/index.ts +21 -21
- package/src/errors/plugin-error.ts +134 -134
- package/src/handles.ts +297 -297
- package/src/host-utils.ts +67 -67
- package/src/index.ts +7 -7
- package/src/massParameters.ops.ts +246 -246
- package/src/massParameters.ts +427 -427
- package/src/types.ts +16 -16
- package/test/drawingContract.test.mjs +288 -0
- package/test/errors.test.mjs +185 -184
- package/test/massParameters.test.mjs +952 -952
- package/tsconfig.json +22 -22
- package/tsup.config.ts +12 -12
- package/api-manifest.json +0 -9618
|
@@ -1,234 +1,234 @@
|
|
|
1
|
-
import * as z from "zod"
|
|
2
|
-
import { PluginApiReturn } from "../../../types"
|
|
3
|
-
// Type-only: src/handles.ts type-only-imports ArenaKind from this file, so the
|
|
4
|
-
// cycle stays purely type-level and is erased at emit.
|
|
5
|
-
import type { AnyArenaHandle } from "../../../handles"
|
|
6
|
-
import { Handle } from "../../../handles"
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The 13 registry-arena handle kinds — the releasable families. Entity-style
|
|
10
|
-
* handles (component / material / underlay / terrain / importJob / comment) are
|
|
11
|
-
* raw engine ids with no arena entry and therefore no lifecycle: passing one to
|
|
12
|
-
* `release` is a silent no-op like any other unknown id.
|
|
13
|
-
*/
|
|
14
|
-
export const ArenaKind = z.enum([
|
|
15
|
-
"vec3",
|
|
16
|
-
"quat",
|
|
17
|
-
"line",
|
|
18
|
-
"arc",
|
|
19
|
-
"spline",
|
|
20
|
-
"circle",
|
|
21
|
-
"profile",
|
|
22
|
-
"contour",
|
|
23
|
-
"brep",
|
|
24
|
-
"face",
|
|
25
|
-
"edge",
|
|
26
|
-
"halfedge",
|
|
27
|
-
"vertex",
|
|
28
|
-
])
|
|
29
|
-
export type ArenaKind = z.infer<typeof ArenaKind>
|
|
30
|
-
|
|
31
|
-
/** Max handles accepted by a single `release` / `endScope(retain)` call. */
|
|
32
|
-
export const RELEASE_BATCH_MAX = 10_000
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* An opaque token identifying a handle scope opened by
|
|
36
|
-
* {@linkcode PluginCoreHandlesApi.beginScope}. It is NOT an arena handle —
|
|
37
|
-
* it pins no memory, and `release(token)` is a silent no-op; only
|
|
38
|
-
* {@linkcode PluginCoreHandlesApi.endScope} consumes it.
|
|
39
|
-
*/
|
|
40
|
-
export type ScopeToken = string
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Handle lifecycle — free host-side handle registry entries the plugin no
|
|
44
|
-
* longer needs, individually ({@linkcode release}), by kind
|
|
45
|
-
* ({@linkcode releaseAll}), or as a mint-recording region
|
|
46
|
-
* ({@linkcode beginScope} / {@linkcode endScope}).
|
|
47
|
-
*
|
|
48
|
-
* Releasing is a handle-lifecycle operation only: it frees the registry entry
|
|
49
|
-
* (host memory + quota room) and makes the handle unresolvable. It never
|
|
50
|
-
* deletes engine-side geometry or scene entities.
|
|
51
|
-
*
|
|
52
|
-
* Accessed via `snaptrude.core.handles`.
|
|
53
|
-
*/
|
|
54
|
-
export abstract class PluginCoreHandlesApi {
|
|
55
|
-
constructor() {}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Free arena handles in bulk. Unknown, foreign, or already-released ids are
|
|
59
|
-
* silent no-ops — there is no per-id result and no count, so responses can
|
|
60
|
-
* never be used as an existence oracle.
|
|
61
|
-
*
|
|
62
|
-
* @param handles The handles to release (max {@linkcode RELEASE_BATCH_MAX} per call)
|
|
63
|
-
* @returns Nothing
|
|
64
|
-
*
|
|
65
|
-
* # Example
|
|
66
|
-
* ```ts
|
|
67
|
-
* const faces = await snaptrude.core.geom.query.brep.listFaces(brep)
|
|
68
|
-
* // ... read what you need ...
|
|
69
|
-
* await snaptrude.core.handles.release(faces)
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
public abstract release(handles: ReadonlyArray<AnyArenaHandle>): PluginApiReturn<void>
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Free every live arena handle of one kind, or ALL arena handles when the
|
|
76
|
-
* kind is omitted. Useful at batch boundaries — e.g. a poll loop that mints
|
|
77
|
-
* a fresh footprint contour per tick.
|
|
78
|
-
*
|
|
79
|
-
* @param kind Optional arena kind to restrict the sweep to
|
|
80
|
-
* @returns Nothing
|
|
81
|
-
*
|
|
82
|
-
* # Example
|
|
83
|
-
* ```ts
|
|
84
|
-
* const footprint = await snaptrude.design.query.spaces.getFootprint(space)
|
|
85
|
-
* // ... measure ...
|
|
86
|
-
* await snaptrude.core.handles.releaseAll("contour")
|
|
87
|
-
* ```
|
|
88
|
-
*/
|
|
89
|
-
public abstract releaseAll(kind?: ArenaKind): PluginApiReturn<void>
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Open a mint-recording scope: every arena handle MINTED after this call
|
|
93
|
-
* (fresh mints only — identity-deduped re-registrations of pre-existing
|
|
94
|
-
* objects are not captured) is freed when the matching
|
|
95
|
-
* {@linkcode endScope} runs. Scopes nest, up to 64 deep — always pair
|
|
96
|
-
* begin/end in try/finally.
|
|
97
|
-
*
|
|
98
|
-
* @returns The scope token to pass to {@linkcode endScope}
|
|
99
|
-
*
|
|
100
|
-
* # Example
|
|
101
|
-
* ```ts
|
|
102
|
-
* for (const space of spaces) {
|
|
103
|
-
* const scope = await snaptrude.core.handles.beginScope()
|
|
104
|
-
* try {
|
|
105
|
-
* const footprint = await snaptrude.design.query.spaces.getFootprint(space)
|
|
106
|
-
* const area = await snaptrude.core.geom.query.contour.getArea(footprint)
|
|
107
|
-
* } finally {
|
|
108
|
-
* await snaptrude.core.handles.endScope(scope) // footprint (and intermediates) freed
|
|
109
|
-
* }
|
|
110
|
-
* }
|
|
111
|
-
* ```
|
|
112
|
-
*/
|
|
113
|
-
public abstract beginScope(): PluginApiReturn<ScopeToken>
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Close a scope by its token and free every handle it recorded, except those
|
|
117
|
-
* listed in `retain`. Retained handles are promoted to the enclosing scope
|
|
118
|
-
* (if any), so nesting composes like block scopes. Closing is
|
|
119
|
-
* token-addressed: an out-of-order close (interleaved async tasks) frees
|
|
120
|
-
* only that scope's mints and leaves other open scopes intact. Always pair
|
|
121
|
-
* begin/end in try/finally so a thrown body cannot leak the scope.
|
|
122
|
-
*
|
|
123
|
-
* @param scope The token returned by the matching {@linkcode beginScope}
|
|
124
|
-
* @param retain Handles minted inside the scope that must survive it
|
|
125
|
-
* @returns Nothing
|
|
126
|
-
*
|
|
127
|
-
* # Example
|
|
128
|
-
* ```ts
|
|
129
|
-
* const scope = await snaptrude.core.handles.beginScope()
|
|
130
|
-
* const outline = await snaptrude.design.query.spaces.getFootprint(space)
|
|
131
|
-
* const outer = await snaptrude.core.geom.query.contour.getOuterProfile(outline)
|
|
132
|
-
* await snaptrude.core.handles.endScope(scope, [outer]) // outline freed, outer survives
|
|
133
|
-
* ```
|
|
134
|
-
*/
|
|
135
|
-
public abstract endScope(
|
|
136
|
-
scope: ScopeToken,
|
|
137
|
-
retain?: ReadonlyArray<AnyArenaHandle>
|
|
138
|
-
): PluginApiReturn<void>
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Live handle-registry statistics for the calling plugin, plus the host
|
|
142
|
-
* page's JS heap usage (when the browser exposes it). Diagnostic surface for
|
|
143
|
-
* verifying that releases actually shrink host memory.
|
|
144
|
-
*
|
|
145
|
-
* @returns Arena entry counts, open scope depth, and host heap bytes
|
|
146
|
-
*
|
|
147
|
-
* # Example
|
|
148
|
-
* ```ts
|
|
149
|
-
* const before = await snaptrude.core.handles.stats()
|
|
150
|
-
* await snaptrude.core.handles.releaseAll("vec3")
|
|
151
|
-
* const after = await snaptrude.core.handles.stats()
|
|
152
|
-
* console.log(`freed ${before.values - after.values} value entries`)
|
|
153
|
-
* ```
|
|
154
|
-
*/
|
|
155
|
-
public abstract stats(): PluginApiReturn<PluginHandlesStatsResult>
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Wire-normalize one handle argument: a raw id string passes through; a live
|
|
160
|
-
* `Handle` instance (direct host callers — console harness, host-internal) or a
|
|
161
|
-
* structured-clone-stripped `{id}` / tagged `{__h}` shape collapses to its id.
|
|
162
|
-
* Deliberately shape-lax beyond that (non-empty string) — a malformed id is
|
|
163
|
-
* just an id that resolves nowhere (anti-oracle).
|
|
164
|
-
*/
|
|
165
|
-
const handleIdWire = z.preprocess((v) => {
|
|
166
|
-
if (typeof v === "string") return v
|
|
167
|
-
if (v instanceof Handle) return v.id
|
|
168
|
-
if (v && typeof v === "object") {
|
|
169
|
-
const o = v as Record<string, unknown>
|
|
170
|
-
if (typeof o.__h === "string") return o.__h
|
|
171
|
-
if (typeof o.id === "string") return o.id
|
|
172
|
-
}
|
|
173
|
-
return v
|
|
174
|
-
}, z.string().min(1))
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Arguments for {@linkcode PluginCoreHandlesApi.release}.
|
|
178
|
-
*
|
|
179
|
-
* | Property | Type | Description |
|
|
180
|
-
* |---|---|---|
|
|
181
|
-
* | `handles` | `string[]` | Handles to release (≤ {@linkcode RELEASE_BATCH_MAX}) |
|
|
182
|
-
*/
|
|
183
|
-
export const PluginHandlesReleaseArgs = z.object({
|
|
184
|
-
handles: z.array(handleIdWire).max(RELEASE_BATCH_MAX),
|
|
185
|
-
})
|
|
186
|
-
export type PluginHandlesReleaseArgs = z.infer<typeof PluginHandlesReleaseArgs>
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Arguments for {@linkcode PluginCoreHandlesApi.releaseAll}.
|
|
190
|
-
*
|
|
191
|
-
* | Property | Type | Description |
|
|
192
|
-
* |---|---|---|
|
|
193
|
-
* | `kind` | {@linkcode ArenaKind} (optional) | Restrict the sweep to one kind |
|
|
194
|
-
*/
|
|
195
|
-
export const PluginHandlesReleaseAllArgs = z.object({
|
|
196
|
-
kind: ArenaKind.optional(),
|
|
197
|
-
})
|
|
198
|
-
export type PluginHandlesReleaseAllArgs = z.infer<typeof PluginHandlesReleaseAllArgs>
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Arguments for {@linkcode PluginCoreHandlesApi.endScope}.
|
|
202
|
-
*
|
|
203
|
-
* | Property | Type | Description |
|
|
204
|
-
* |---|---|---|
|
|
205
|
-
* | `scope` | {@linkcode ScopeToken} | Token from the matching `beginScope` |
|
|
206
|
-
* | `retain` | `string[]` (optional) | Scope-minted handles that must survive |
|
|
207
|
-
*/
|
|
208
|
-
export const PluginHandlesEndScopeArgs = z.object({
|
|
209
|
-
scope: z.string().regex(/^scope_[A-Za-z0-9_-]+$/, 'expected a "scope" token'),
|
|
210
|
-
retain: z.array(handleIdWire).max(RELEASE_BATCH_MAX).optional(),
|
|
211
|
-
})
|
|
212
|
-
export type PluginHandlesEndScopeArgs = z.infer<typeof PluginHandlesEndScopeArgs>
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Result of {@linkcode PluginCoreHandlesApi.stats}.
|
|
216
|
-
*
|
|
217
|
-
* | Property | Type | Description |
|
|
218
|
-
* |---|---|---|
|
|
219
|
-
* | `resources` | `number` | Live resource-arena entries (profile/contour) |
|
|
220
|
-
* | `values` | `number` | Live value-arena entries (vec3/quat/line/arc/spline/circle) |
|
|
221
|
-
* | `topology` | `number` | Live topology-arena entries (brep/face/edge/halfedge/vertex) |
|
|
222
|
-
* | `scopes` | `number` | Currently open handle scopes |
|
|
223
|
-
* | `hostHeapUsedBytes` | `number \| null` | Host page `usedJSHeapSize` (null where unsupported) |
|
|
224
|
-
* | `hostHeapTotalBytes` | `number \| null` | Host page `totalJSHeapSize` (null where unsupported) |
|
|
225
|
-
*/
|
|
226
|
-
export const PluginHandlesStatsResult = z.object({
|
|
227
|
-
resources: z.number().int().nonnegative(),
|
|
228
|
-
values: z.number().int().nonnegative(),
|
|
229
|
-
topology: z.number().int().nonnegative(),
|
|
230
|
-
scopes: z.number().int().nonnegative(),
|
|
231
|
-
hostHeapUsedBytes: z.number().nullable(),
|
|
232
|
-
hostHeapTotalBytes: z.number().nullable(),
|
|
233
|
-
})
|
|
234
|
-
export type PluginHandlesStatsResult = z.infer<typeof PluginHandlesStatsResult>
|
|
1
|
+
import * as z from "zod"
|
|
2
|
+
import { PluginApiReturn } from "../../../types"
|
|
3
|
+
// Type-only: src/handles.ts type-only-imports ArenaKind from this file, so the
|
|
4
|
+
// cycle stays purely type-level and is erased at emit.
|
|
5
|
+
import type { AnyArenaHandle } from "../../../handles"
|
|
6
|
+
import { Handle } from "../../../handles"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The 13 registry-arena handle kinds — the releasable families. Entity-style
|
|
10
|
+
* handles (component / material / underlay / terrain / importJob / comment) are
|
|
11
|
+
* raw engine ids with no arena entry and therefore no lifecycle: passing one to
|
|
12
|
+
* `release` is a silent no-op like any other unknown id.
|
|
13
|
+
*/
|
|
14
|
+
export const ArenaKind = z.enum([
|
|
15
|
+
"vec3",
|
|
16
|
+
"quat",
|
|
17
|
+
"line",
|
|
18
|
+
"arc",
|
|
19
|
+
"spline",
|
|
20
|
+
"circle",
|
|
21
|
+
"profile",
|
|
22
|
+
"contour",
|
|
23
|
+
"brep",
|
|
24
|
+
"face",
|
|
25
|
+
"edge",
|
|
26
|
+
"halfedge",
|
|
27
|
+
"vertex",
|
|
28
|
+
])
|
|
29
|
+
export type ArenaKind = z.infer<typeof ArenaKind>
|
|
30
|
+
|
|
31
|
+
/** Max handles accepted by a single `release` / `endScope(retain)` call. */
|
|
32
|
+
export const RELEASE_BATCH_MAX = 10_000
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* An opaque token identifying a handle scope opened by
|
|
36
|
+
* {@linkcode PluginCoreHandlesApi.beginScope}. It is NOT an arena handle —
|
|
37
|
+
* it pins no memory, and `release(token)` is a silent no-op; only
|
|
38
|
+
* {@linkcode PluginCoreHandlesApi.endScope} consumes it.
|
|
39
|
+
*/
|
|
40
|
+
export type ScopeToken = string
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Handle lifecycle — free host-side handle registry entries the plugin no
|
|
44
|
+
* longer needs, individually ({@linkcode release}), by kind
|
|
45
|
+
* ({@linkcode releaseAll}), or as a mint-recording region
|
|
46
|
+
* ({@linkcode beginScope} / {@linkcode endScope}).
|
|
47
|
+
*
|
|
48
|
+
* Releasing is a handle-lifecycle operation only: it frees the registry entry
|
|
49
|
+
* (host memory + quota room) and makes the handle unresolvable. It never
|
|
50
|
+
* deletes engine-side geometry or scene entities.
|
|
51
|
+
*
|
|
52
|
+
* Accessed via `snaptrude.core.handles`.
|
|
53
|
+
*/
|
|
54
|
+
export abstract class PluginCoreHandlesApi {
|
|
55
|
+
constructor() {}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Free arena handles in bulk. Unknown, foreign, or already-released ids are
|
|
59
|
+
* silent no-ops — there is no per-id result and no count, so responses can
|
|
60
|
+
* never be used as an existence oracle.
|
|
61
|
+
*
|
|
62
|
+
* @param handles The handles to release (max {@linkcode RELEASE_BATCH_MAX} per call)
|
|
63
|
+
* @returns Nothing
|
|
64
|
+
*
|
|
65
|
+
* # Example
|
|
66
|
+
* ```ts
|
|
67
|
+
* const faces = await snaptrude.core.geom.query.brep.listFaces(brep)
|
|
68
|
+
* // ... read what you need ...
|
|
69
|
+
* await snaptrude.core.handles.release(faces)
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
public abstract release(handles: ReadonlyArray<AnyArenaHandle>): PluginApiReturn<void>
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Free every live arena handle of one kind, or ALL arena handles when the
|
|
76
|
+
* kind is omitted. Useful at batch boundaries — e.g. a poll loop that mints
|
|
77
|
+
* a fresh footprint contour per tick.
|
|
78
|
+
*
|
|
79
|
+
* @param kind Optional arena kind to restrict the sweep to
|
|
80
|
+
* @returns Nothing
|
|
81
|
+
*
|
|
82
|
+
* # Example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const footprint = await snaptrude.design.query.spaces.getFootprint(space)
|
|
85
|
+
* // ... measure ...
|
|
86
|
+
* await snaptrude.core.handles.releaseAll("contour")
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
public abstract releaseAll(kind?: ArenaKind): PluginApiReturn<void>
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Open a mint-recording scope: every arena handle MINTED after this call
|
|
93
|
+
* (fresh mints only — identity-deduped re-registrations of pre-existing
|
|
94
|
+
* objects are not captured) is freed when the matching
|
|
95
|
+
* {@linkcode endScope} runs. Scopes nest, up to 64 deep — always pair
|
|
96
|
+
* begin/end in try/finally.
|
|
97
|
+
*
|
|
98
|
+
* @returns The scope token to pass to {@linkcode endScope}
|
|
99
|
+
*
|
|
100
|
+
* # Example
|
|
101
|
+
* ```ts
|
|
102
|
+
* for (const space of spaces) {
|
|
103
|
+
* const scope = await snaptrude.core.handles.beginScope()
|
|
104
|
+
* try {
|
|
105
|
+
* const footprint = await snaptrude.design.query.spaces.getFootprint(space)
|
|
106
|
+
* const area = await snaptrude.core.geom.query.contour.getArea(footprint)
|
|
107
|
+
* } finally {
|
|
108
|
+
* await snaptrude.core.handles.endScope(scope) // footprint (and intermediates) freed
|
|
109
|
+
* }
|
|
110
|
+
* }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
public abstract beginScope(): PluginApiReturn<ScopeToken>
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Close a scope by its token and free every handle it recorded, except those
|
|
117
|
+
* listed in `retain`. Retained handles are promoted to the enclosing scope
|
|
118
|
+
* (if any), so nesting composes like block scopes. Closing is
|
|
119
|
+
* token-addressed: an out-of-order close (interleaved async tasks) frees
|
|
120
|
+
* only that scope's mints and leaves other open scopes intact. Always pair
|
|
121
|
+
* begin/end in try/finally so a thrown body cannot leak the scope.
|
|
122
|
+
*
|
|
123
|
+
* @param scope The token returned by the matching {@linkcode beginScope}
|
|
124
|
+
* @param retain Handles minted inside the scope that must survive it
|
|
125
|
+
* @returns Nothing
|
|
126
|
+
*
|
|
127
|
+
* # Example
|
|
128
|
+
* ```ts
|
|
129
|
+
* const scope = await snaptrude.core.handles.beginScope()
|
|
130
|
+
* const outline = await snaptrude.design.query.spaces.getFootprint(space)
|
|
131
|
+
* const outer = await snaptrude.core.geom.query.contour.getOuterProfile(outline)
|
|
132
|
+
* await snaptrude.core.handles.endScope(scope, [outer]) // outline freed, outer survives
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
public abstract endScope(
|
|
136
|
+
scope: ScopeToken,
|
|
137
|
+
retain?: ReadonlyArray<AnyArenaHandle>
|
|
138
|
+
): PluginApiReturn<void>
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Live handle-registry statistics for the calling plugin, plus the host
|
|
142
|
+
* page's JS heap usage (when the browser exposes it). Diagnostic surface for
|
|
143
|
+
* verifying that releases actually shrink host memory.
|
|
144
|
+
*
|
|
145
|
+
* @returns Arena entry counts, open scope depth, and host heap bytes
|
|
146
|
+
*
|
|
147
|
+
* # Example
|
|
148
|
+
* ```ts
|
|
149
|
+
* const before = await snaptrude.core.handles.stats()
|
|
150
|
+
* await snaptrude.core.handles.releaseAll("vec3")
|
|
151
|
+
* const after = await snaptrude.core.handles.stats()
|
|
152
|
+
* console.log(`freed ${before.values - after.values} value entries`)
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
public abstract stats(): PluginApiReturn<PluginHandlesStatsResult>
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Wire-normalize one handle argument: a raw id string passes through; a live
|
|
160
|
+
* `Handle` instance (direct host callers — console harness, host-internal) or a
|
|
161
|
+
* structured-clone-stripped `{id}` / tagged `{__h}` shape collapses to its id.
|
|
162
|
+
* Deliberately shape-lax beyond that (non-empty string) — a malformed id is
|
|
163
|
+
* just an id that resolves nowhere (anti-oracle).
|
|
164
|
+
*/
|
|
165
|
+
const handleIdWire = z.preprocess((v) => {
|
|
166
|
+
if (typeof v === "string") return v
|
|
167
|
+
if (v instanceof Handle) return v.id
|
|
168
|
+
if (v && typeof v === "object") {
|
|
169
|
+
const o = v as Record<string, unknown>
|
|
170
|
+
if (typeof o.__h === "string") return o.__h
|
|
171
|
+
if (typeof o.id === "string") return o.id
|
|
172
|
+
}
|
|
173
|
+
return v
|
|
174
|
+
}, z.string().min(1))
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Arguments for {@linkcode PluginCoreHandlesApi.release}.
|
|
178
|
+
*
|
|
179
|
+
* | Property | Type | Description |
|
|
180
|
+
* |---|---|---|
|
|
181
|
+
* | `handles` | `string[]` | Handles to release (≤ {@linkcode RELEASE_BATCH_MAX}) |
|
|
182
|
+
*/
|
|
183
|
+
export const PluginHandlesReleaseArgs = z.object({
|
|
184
|
+
handles: z.array(handleIdWire).max(RELEASE_BATCH_MAX),
|
|
185
|
+
})
|
|
186
|
+
export type PluginHandlesReleaseArgs = z.infer<typeof PluginHandlesReleaseArgs>
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Arguments for {@linkcode PluginCoreHandlesApi.releaseAll}.
|
|
190
|
+
*
|
|
191
|
+
* | Property | Type | Description |
|
|
192
|
+
* |---|---|---|
|
|
193
|
+
* | `kind` | {@linkcode ArenaKind} (optional) | Restrict the sweep to one kind |
|
|
194
|
+
*/
|
|
195
|
+
export const PluginHandlesReleaseAllArgs = z.object({
|
|
196
|
+
kind: ArenaKind.optional(),
|
|
197
|
+
})
|
|
198
|
+
export type PluginHandlesReleaseAllArgs = z.infer<typeof PluginHandlesReleaseAllArgs>
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Arguments for {@linkcode PluginCoreHandlesApi.endScope}.
|
|
202
|
+
*
|
|
203
|
+
* | Property | Type | Description |
|
|
204
|
+
* |---|---|---|
|
|
205
|
+
* | `scope` | {@linkcode ScopeToken} | Token from the matching `beginScope` |
|
|
206
|
+
* | `retain` | `string[]` (optional) | Scope-minted handles that must survive |
|
|
207
|
+
*/
|
|
208
|
+
export const PluginHandlesEndScopeArgs = z.object({
|
|
209
|
+
scope: z.string().regex(/^scope_[A-Za-z0-9_-]+$/, 'expected a "scope" token'),
|
|
210
|
+
retain: z.array(handleIdWire).max(RELEASE_BATCH_MAX).optional(),
|
|
211
|
+
})
|
|
212
|
+
export type PluginHandlesEndScopeArgs = z.infer<typeof PluginHandlesEndScopeArgs>
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Result of {@linkcode PluginCoreHandlesApi.stats}.
|
|
216
|
+
*
|
|
217
|
+
* | Property | Type | Description |
|
|
218
|
+
* |---|---|---|
|
|
219
|
+
* | `resources` | `number` | Live resource-arena entries (profile/contour) |
|
|
220
|
+
* | `values` | `number` | Live value-arena entries (vec3/quat/line/arc/spline/circle) |
|
|
221
|
+
* | `topology` | `number` | Live topology-arena entries (brep/face/edge/halfedge/vertex) |
|
|
222
|
+
* | `scopes` | `number` | Currently open handle scopes |
|
|
223
|
+
* | `hostHeapUsedBytes` | `number \| null` | Host page `usedJSHeapSize` (null where unsupported) |
|
|
224
|
+
* | `hostHeapTotalBytes` | `number \| null` | Host page `totalJSHeapSize` (null where unsupported) |
|
|
225
|
+
*/
|
|
226
|
+
export const PluginHandlesStatsResult = z.object({
|
|
227
|
+
resources: z.number().int().nonnegative(),
|
|
228
|
+
values: z.number().int().nonnegative(),
|
|
229
|
+
topology: z.number().int().nonnegative(),
|
|
230
|
+
scopes: z.number().int().nonnegative(),
|
|
231
|
+
hostHeapUsedBytes: z.number().nullable(),
|
|
232
|
+
hostHeapTotalBytes: z.number().nullable(),
|
|
233
|
+
})
|
|
234
|
+
export type PluginHandlesStatsResult = z.infer<typeof PluginHandlesStatsResult>
|
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
import * as z from "zod"
|
|
2
|
-
import { PluginApiReturn } from "../../../types"
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Undo / redo of committed history entries.
|
|
6
|
-
*
|
|
7
|
-
* History steps operate on Snaptrude's command stack: {@linkcode PluginHistoryApi.undo}
|
|
8
|
-
* steps back over committed entries, {@linkcode PluginHistoryApi.redo} re-applies
|
|
9
|
-
* undone ones. Both take an optional step count (default 1) and report how many
|
|
10
|
-
* steps were actually applied — fewer than requested when the stack runs out.
|
|
11
|
-
*
|
|
12
|
-
* Accessed via `snaptrude.core.history`.
|
|
13
|
-
*/
|
|
14
|
-
export abstract class PluginHistoryApi {
|
|
15
|
-
constructor() {}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Step back over committed history entries.
|
|
19
|
-
*
|
|
20
|
-
* @param steps - (Optional) The number of entries to undo (default 1).
|
|
21
|
-
* @returns A {@linkcode PluginHistoryStepResult} with `stepsApplied` — the
|
|
22
|
-
* entries actually undone (≤ `steps`; fewer if the undo stack ran out).
|
|
23
|
-
*
|
|
24
|
-
* @examplePrompt Undo my last change
|
|
25
|
-
* @examplePrompt Undo the last 3 actions
|
|
26
|
-
* @examplePrompt Revert what I just did to the model
|
|
27
|
-
* @examplePrompt Step back one change
|
|
28
|
-
* @examplePrompt Take back that last edit
|
|
29
|
-
*
|
|
30
|
-
* # Example
|
|
31
|
-
* ```ts
|
|
32
|
-
* await snaptrude.core.history.undo() // one step
|
|
33
|
-
* await snaptrude.core.history.undo(3) // up to three steps
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
public abstract undo(steps?: number): PluginApiReturn<PluginHistoryStepResult>
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Step forward over previously undone entries. Symmetric with
|
|
40
|
-
* {@linkcode PluginHistoryApi.undo}.
|
|
41
|
-
*
|
|
42
|
-
* @param steps - (Optional) The number of entries to redo (default 1).
|
|
43
|
-
* @returns A {@linkcode PluginHistoryStepResult} with `stepsApplied` — the
|
|
44
|
-
* entries actually redone (≤ `steps`; fewer if the redo stack ran out).
|
|
45
|
-
*
|
|
46
|
-
* @examplePrompt Redo the change I just undid
|
|
47
|
-
* @examplePrompt Redo the last two undone actions
|
|
48
|
-
* @examplePrompt Bring back the edit I reverted
|
|
49
|
-
* @examplePrompt Step forward again in the history
|
|
50
|
-
*
|
|
51
|
-
* # Example
|
|
52
|
-
* ```ts
|
|
53
|
-
* await snaptrude.core.history.redo()
|
|
54
|
-
* await snaptrude.core.history.redo(2)
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
public abstract redo(steps?: number): PluginApiReturn<PluginHistoryStepResult>
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Arguments for {@linkcode PluginHistoryApi.undo} / {@linkcode PluginHistoryApi.redo}.
|
|
62
|
-
*
|
|
63
|
-
* | Property | Type | Description |
|
|
64
|
-
* |---|---|---|
|
|
65
|
-
* | `steps` | `number?` | Number of history entries to step (positive integer). Defaults to 1. |
|
|
66
|
-
*/
|
|
67
|
-
export const PluginHistoryStepArgs = z.object({
|
|
68
|
-
steps: z.number().int().positive().optional(),
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
export type PluginHistoryStepArgs = z.infer<typeof PluginHistoryStepArgs>
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Result of {@linkcode PluginHistoryApi.undo} / {@linkcode PluginHistoryApi.redo}.
|
|
75
|
-
*
|
|
76
|
-
* | Property | Type | Description |
|
|
77
|
-
* |---|---|---|
|
|
78
|
-
* | `stepsApplied` | `number` | History entries actually stepped — `≤ steps`, fewer when the stack ran out. |
|
|
79
|
-
*/
|
|
80
|
-
export const PluginHistoryStepResult = z.object({
|
|
81
|
-
stepsApplied: z.number().int().nonnegative(),
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
export type PluginHistoryStepResult = z.infer<typeof PluginHistoryStepResult>
|
|
1
|
+
import * as z from "zod"
|
|
2
|
+
import { PluginApiReturn } from "../../../types"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Undo / redo of committed history entries.
|
|
6
|
+
*
|
|
7
|
+
* History steps operate on Snaptrude's command stack: {@linkcode PluginHistoryApi.undo}
|
|
8
|
+
* steps back over committed entries, {@linkcode PluginHistoryApi.redo} re-applies
|
|
9
|
+
* undone ones. Both take an optional step count (default 1) and report how many
|
|
10
|
+
* steps were actually applied — fewer than requested when the stack runs out.
|
|
11
|
+
*
|
|
12
|
+
* Accessed via `snaptrude.core.history`.
|
|
13
|
+
*/
|
|
14
|
+
export abstract class PluginHistoryApi {
|
|
15
|
+
constructor() {}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Step back over committed history entries.
|
|
19
|
+
*
|
|
20
|
+
* @param steps - (Optional) The number of entries to undo (default 1).
|
|
21
|
+
* @returns A {@linkcode PluginHistoryStepResult} with `stepsApplied` — the
|
|
22
|
+
* entries actually undone (≤ `steps`; fewer if the undo stack ran out).
|
|
23
|
+
*
|
|
24
|
+
* @examplePrompt Undo my last change
|
|
25
|
+
* @examplePrompt Undo the last 3 actions
|
|
26
|
+
* @examplePrompt Revert what I just did to the model
|
|
27
|
+
* @examplePrompt Step back one change
|
|
28
|
+
* @examplePrompt Take back that last edit
|
|
29
|
+
*
|
|
30
|
+
* # Example
|
|
31
|
+
* ```ts
|
|
32
|
+
* await snaptrude.core.history.undo() // one step
|
|
33
|
+
* await snaptrude.core.history.undo(3) // up to three steps
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
public abstract undo(steps?: number): PluginApiReturn<PluginHistoryStepResult>
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Step forward over previously undone entries. Symmetric with
|
|
40
|
+
* {@linkcode PluginHistoryApi.undo}.
|
|
41
|
+
*
|
|
42
|
+
* @param steps - (Optional) The number of entries to redo (default 1).
|
|
43
|
+
* @returns A {@linkcode PluginHistoryStepResult} with `stepsApplied` — the
|
|
44
|
+
* entries actually redone (≤ `steps`; fewer if the redo stack ran out).
|
|
45
|
+
*
|
|
46
|
+
* @examplePrompt Redo the change I just undid
|
|
47
|
+
* @examplePrompt Redo the last two undone actions
|
|
48
|
+
* @examplePrompt Bring back the edit I reverted
|
|
49
|
+
* @examplePrompt Step forward again in the history
|
|
50
|
+
*
|
|
51
|
+
* # Example
|
|
52
|
+
* ```ts
|
|
53
|
+
* await snaptrude.core.history.redo()
|
|
54
|
+
* await snaptrude.core.history.redo(2)
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
public abstract redo(steps?: number): PluginApiReturn<PluginHistoryStepResult>
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Arguments for {@linkcode PluginHistoryApi.undo} / {@linkcode PluginHistoryApi.redo}.
|
|
62
|
+
*
|
|
63
|
+
* | Property | Type | Description |
|
|
64
|
+
* |---|---|---|
|
|
65
|
+
* | `steps` | `number?` | Number of history entries to step (positive integer). Defaults to 1. |
|
|
66
|
+
*/
|
|
67
|
+
export const PluginHistoryStepArgs = z.object({
|
|
68
|
+
steps: z.number().int().positive().optional(),
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
export type PluginHistoryStepArgs = z.infer<typeof PluginHistoryStepArgs>
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Result of {@linkcode PluginHistoryApi.undo} / {@linkcode PluginHistoryApi.redo}.
|
|
75
|
+
*
|
|
76
|
+
* | Property | Type | Description |
|
|
77
|
+
* |---|---|---|
|
|
78
|
+
* | `stepsApplied` | `number` | History entries actually stepped — `≤ steps`, fewer when the stack ran out. |
|
|
79
|
+
*/
|
|
80
|
+
export const PluginHistoryStepResult = z.object({
|
|
81
|
+
stepsApplied: z.number().int().nonnegative(),
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
export type PluginHistoryStepResult = z.infer<typeof PluginHistoryStepResult>
|