narraleaf-studio 0.7.0 → 0.8.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/_api.d.ts +360 -1855
- package/dist/plugin.d.ts +10 -0
- package/dist/runtime.d.ts +2 -0
- package/package.json +1 -1
package/dist/_api.d.ts
CHANGED
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
// Generated by dts-bundle-generator v9.5.1
|
|
12
12
|
|
|
13
13
|
import { LucideIcon } from 'lucide-react';
|
|
14
|
-
import { TextGlyphOrientation, TextWritingMode as NlrTextWritingMode } from 'narraleaf-react';
|
|
15
14
|
import React$1 from 'react';
|
|
16
15
|
import { ComponentType, InputHTMLAttributes, ReactElement, ReactNode, RefObject } from 'react';
|
|
17
16
|
|
|
@@ -1422,92 +1421,6 @@ type StoryAlignPositionValue = {
|
|
|
1422
1421
|
xoffset?: number;
|
|
1423
1422
|
yoffset?: number;
|
|
1424
1423
|
};
|
|
1425
|
-
type BlueprintDebugEvent = {
|
|
1426
|
-
type: "execution.started";
|
|
1427
|
-
executionId: string;
|
|
1428
|
-
blueprintId: string;
|
|
1429
|
-
} | {
|
|
1430
|
-
type: "execution.finished";
|
|
1431
|
-
executionId: string;
|
|
1432
|
-
blueprintId: string;
|
|
1433
|
-
} | {
|
|
1434
|
-
type: "execution.cancelled";
|
|
1435
|
-
executionId: string;
|
|
1436
|
-
blueprintId?: string;
|
|
1437
|
-
eventId?: string;
|
|
1438
|
-
graphId?: string;
|
|
1439
|
-
nodeId?: string;
|
|
1440
|
-
reason?: string;
|
|
1441
|
-
} | {
|
|
1442
|
-
type: "node.enter";
|
|
1443
|
-
executionId: string;
|
|
1444
|
-
nodeId: string;
|
|
1445
|
-
} | {
|
|
1446
|
-
type: "node.exit";
|
|
1447
|
-
executionId: string;
|
|
1448
|
-
nodeId: string;
|
|
1449
|
-
} | {
|
|
1450
|
-
type: "state.read";
|
|
1451
|
-
scope: string;
|
|
1452
|
-
key: string;
|
|
1453
|
-
} | {
|
|
1454
|
-
type: "state.write";
|
|
1455
|
-
scope: string;
|
|
1456
|
-
key: string;
|
|
1457
|
-
} | {
|
|
1458
|
-
type: "binding.evaluated";
|
|
1459
|
-
bindingId: string;
|
|
1460
|
-
} | {
|
|
1461
|
-
type: "function.call";
|
|
1462
|
-
functionId: string;
|
|
1463
|
-
} | {
|
|
1464
|
-
type: "function.return";
|
|
1465
|
-
functionId: string;
|
|
1466
|
-
} | {
|
|
1467
|
-
type: "devtools.log";
|
|
1468
|
-
level: string;
|
|
1469
|
-
message: string;
|
|
1470
|
-
} | {
|
|
1471
|
-
/**
|
|
1472
|
-
* A node ran with one of its required data inputs left unconnected and no value on the
|
|
1473
|
-
* card, so the pin resolved to nothing.
|
|
1474
|
-
*
|
|
1475
|
-
* Its own event rather than a `devtools.log`, because it has a place: an issue list can
|
|
1476
|
-
* put it on a surface, and a repeat of it on the same pin is the same problem rather than
|
|
1477
|
-
* a second line of output. Carries the node's and the pin's English names off the
|
|
1478
|
-
* catalogue, which is what a host that has no node-title map (the shipped game) can still
|
|
1479
|
-
* write into a player's log.
|
|
1480
|
-
*/
|
|
1481
|
-
type: "node.input_missing";
|
|
1482
|
-
executionId: string;
|
|
1483
|
-
nodeId: string;
|
|
1484
|
-
/** The node's display name as its definition declares it. */
|
|
1485
|
-
nodeName: string;
|
|
1486
|
-
/** The unwired pin's label as its definition declares it. */
|
|
1487
|
-
pinLabel: string;
|
|
1488
|
-
blueprintId?: string;
|
|
1489
|
-
eventId?: string;
|
|
1490
|
-
graphId?: string;
|
|
1491
|
-
/** See the note on `execution.error`: what lets a host say "the Quick Menu". */
|
|
1492
|
-
surfaceId?: string;
|
|
1493
|
-
} | {
|
|
1494
|
-
type: "execution.error";
|
|
1495
|
-
executionId: string;
|
|
1496
|
-
message: string;
|
|
1497
|
-
blueprintId?: string;
|
|
1498
|
-
eventId?: string;
|
|
1499
|
-
graphId?: string;
|
|
1500
|
-
nodeId?: string;
|
|
1501
|
-
/**
|
|
1502
|
-
* The UI surface whose graph failed, when the failure happened on one.
|
|
1503
|
-
*
|
|
1504
|
-
* The rest of this event names OUR ids - a blueprint, a graph, a node - none of which an
|
|
1505
|
-
* author can find their way back from. A surface id resolves against the document they
|
|
1506
|
-
* drew, which is what lets a host say "the Quick Menu" rather than "bp:8f2c1a…". Absent on
|
|
1507
|
-
* the global blueprint, which belongs to no surface.
|
|
1508
|
-
*/
|
|
1509
|
-
surfaceId?: string;
|
|
1510
|
-
};
|
|
1511
1424
|
type BlueprintOwnerRef = {
|
|
1512
1425
|
kind: "globalMain";
|
|
1513
1426
|
} | {
|
|
@@ -1747,70 +1660,6 @@ type BlueprintDiagnostic = {
|
|
|
1747
1660
|
/** Source span or module location; M1 opaque */
|
|
1748
1661
|
location?: Record<string, unknown>;
|
|
1749
1662
|
};
|
|
1750
|
-
type LocaleCode = string;
|
|
1751
|
-
type LocalizationLocaleEntry = {
|
|
1752
|
-
code: LocaleCode;
|
|
1753
|
-
/** Author-facing autonym shown to players (e.g. "日本語", never "Japanese"). */
|
|
1754
|
-
displayName: string;
|
|
1755
|
-
/** Optional intermediate fallback locale tried before the source locale. */
|
|
1756
|
-
fallback?: LocaleCode;
|
|
1757
|
-
};
|
|
1758
|
-
type GameLocalizationBundle = {
|
|
1759
|
-
sourceLocale: LocaleCode;
|
|
1760
|
-
locales: LocalizationLocaleEntry[];
|
|
1761
|
-
tables: Record<LocaleCode, Record<string, string>>;
|
|
1762
|
-
/** Named-key source texts (key name → source-language text). */
|
|
1763
|
-
keys?: Record<string, string>;
|
|
1764
|
-
/**
|
|
1765
|
-
* Scene-name source texts (scene id → source-language name), for the scenes this build ships.
|
|
1766
|
-
*
|
|
1767
|
-
* The same job `keys` does for named keys: a translation table only holds the *target* side, so
|
|
1768
|
-
* without this a `scene:` reference read while the game is in the source language has nothing to
|
|
1769
|
-
* render but the id. Assembled from the story documents the bundle carries, so a scene a variant
|
|
1770
|
-
* dropped is absent here too.
|
|
1771
|
-
*/
|
|
1772
|
-
scenes?: Record<string, string>;
|
|
1773
|
-
};
|
|
1774
|
-
type SaveRecordTimes = {
|
|
1775
|
-
/** When this slot was last written, epoch milliseconds; 0 when the record carries no stamp. */
|
|
1776
|
-
savedAt: number;
|
|
1777
|
-
/** When this slot was first written, epoch milliseconds; 0 when the record carries no stamp. */
|
|
1778
|
-
createdAt: number;
|
|
1779
|
-
};
|
|
1780
|
-
type SaveRecordPlaytime = {
|
|
1781
|
-
/** Seconds of play behind the slot; 0 when nothing was recorded. */
|
|
1782
|
-
seconds: number;
|
|
1783
|
-
/** False when the slot carries no reading at all. */
|
|
1784
|
-
recorded: boolean;
|
|
1785
|
-
};
|
|
1786
|
-
type SaveRecordLine = {
|
|
1787
|
-
/** The last sentence shown, or "" when the record carries none. */
|
|
1788
|
-
line: string;
|
|
1789
|
-
/** Who spoke it, or "" when the record carries no speaker (narration, or none yet). */
|
|
1790
|
-
speaker: string;
|
|
1791
|
-
};
|
|
1792
|
-
type SaveRecordStory = {
|
|
1793
|
-
/** The story the save was written in, as an opaque reference; "" when the record carries none. */
|
|
1794
|
-
id: string;
|
|
1795
|
-
/** That story's author-facing name; "" when this build ships no story under that reference. */
|
|
1796
|
-
name: string;
|
|
1797
|
-
};
|
|
1798
|
-
type AutoSaveEntry = {
|
|
1799
|
-
id: string;
|
|
1800
|
-
/** Slot index within the ring. */
|
|
1801
|
-
slot: number;
|
|
1802
|
-
/** When this slot was last written, epoch milliseconds. */
|
|
1803
|
-
timestamp: number;
|
|
1804
|
-
/** When this slot was first written, epoch milliseconds. */
|
|
1805
|
-
createdAt: number;
|
|
1806
|
-
/** Whatever the writer attached as user metadata (null when none). */
|
|
1807
|
-
metadata: unknown;
|
|
1808
|
-
};
|
|
1809
|
-
type VoiceLocaleEntry = {
|
|
1810
|
-
code: LocaleCode;
|
|
1811
|
-
/** Author-facing autonym shown for this voice language (e.g. "日本語"). */
|
|
1812
|
-
displayName: string;
|
|
1813
|
-
};
|
|
1814
1663
|
type AudioClipRegion = {
|
|
1815
1664
|
/** Offset from the start of the clip, in milliseconds. Where playback starts. */
|
|
1816
1665
|
inMs?: number;
|
|
@@ -1838,67 +1687,7 @@ type BlueprintOpenExternalResult = {
|
|
|
1838
1687
|
/** Human-readable reason, null when the page was handed over. */
|
|
1839
1688
|
error: string | null;
|
|
1840
1689
|
};
|
|
1841
|
-
type BlueprintPointerMoveOutcome =
|
|
1842
|
-
/** The cursor is now at the requested point. */
|
|
1843
|
-
"moved"
|
|
1844
|
-
/** This shell cannot move the cursor: a web export, or a host with no platform support. */
|
|
1845
|
-
| "unsupported"
|
|
1846
|
-
/** The move was attempted and failed. */
|
|
1847
|
-
| "failed";
|
|
1848
|
-
type BlueprintPointerMoveResult = {
|
|
1849
|
-
outcome: BlueprintPointerMoveOutcome;
|
|
1850
|
-
error?: string;
|
|
1851
|
-
};
|
|
1852
|
-
declare const BLUEPRINT_POINTER_MOVE_EASINGS: readonly [
|
|
1853
|
-
"linear",
|
|
1854
|
-
"easeIn",
|
|
1855
|
-
"easeOut",
|
|
1856
|
-
"easeInOut"
|
|
1857
|
-
];
|
|
1858
|
-
type BlueprintPointerMoveEasing = (typeof BLUEPRINT_POINTER_MOVE_EASINGS)[number];
|
|
1859
|
-
type BlueprintScreenshotOutcome = "saved" | "failed";
|
|
1860
|
-
type BlueprintScreenshotResult = {
|
|
1861
|
-
outcome: BlueprintScreenshotOutcome;
|
|
1862
|
-
/** The file that was written, absolute, or null when nothing was. */
|
|
1863
|
-
path: string | null;
|
|
1864
|
-
/** Why nothing was written. Null on success. */
|
|
1865
|
-
error: string | null;
|
|
1866
|
-
};
|
|
1867
|
-
type BlueprintOpenScreenshotsResult = {
|
|
1868
|
-
outcome: "opened" | "failed";
|
|
1869
|
-
/** The folder that was opened, absolute, or null when none was. */
|
|
1870
|
-
path: string | null;
|
|
1871
|
-
error: string | null;
|
|
1872
|
-
};
|
|
1873
1690
|
type BlueprintGraphKind = "event" | "function" | "macro";
|
|
1874
|
-
declare const BLUEPRINT_NETWORK_METHODS: readonly [
|
|
1875
|
-
"GET",
|
|
1876
|
-
"POST",
|
|
1877
|
-
"PUT",
|
|
1878
|
-
"PATCH",
|
|
1879
|
-
"DELETE",
|
|
1880
|
-
"HEAD"
|
|
1881
|
-
];
|
|
1882
|
-
type BlueprintNetworkMethod = typeof BLUEPRINT_NETWORK_METHODS[number];
|
|
1883
|
-
type BlueprintNetworkFetchRequest = {
|
|
1884
|
-
url: string;
|
|
1885
|
-
method: BlueprintNetworkMethod;
|
|
1886
|
-
/** Header name -> value. Null and `{}` both mean "send none". */
|
|
1887
|
-
headers: Record<string, string> | null;
|
|
1888
|
-
/** Request body, for the methods that carry one. */
|
|
1889
|
-
body: string | null;
|
|
1890
|
-
timeoutMs: number;
|
|
1891
|
-
};
|
|
1892
|
-
type BlueprintNetworkFetchOutcome = "success" | "httpError" | "networkError" | "timeout";
|
|
1893
|
-
type BlueprintNetworkFetchResult = {
|
|
1894
|
-
outcome: BlueprintNetworkFetchOutcome;
|
|
1895
|
-
/** HTTP status, or 0 when no response was received. */
|
|
1896
|
-
status: number;
|
|
1897
|
-
/** Response body text, present whenever a response arrived. */
|
|
1898
|
-
body: string | null;
|
|
1899
|
-
/** Human-readable failure reason, null on success. */
|
|
1900
|
-
error: string | null;
|
|
1901
|
-
};
|
|
1902
1691
|
type GameBuildPlatform = "windows" | "macos" | "linux" | "web" | "android" | "ios";
|
|
1903
1692
|
type PluginPermissionPersistence = "temporary" | "permanent";
|
|
1904
1693
|
type PluginFileSystemPermissionMode = "read" | "write" | "readwrite";
|
|
@@ -2044,6 +1833,24 @@ declare const PluginRuntimeCapability: {
|
|
|
2044
1833
|
* declared.
|
|
2045
1834
|
*/
|
|
2046
1835
|
readonly StoryCompile: "story.compile";
|
|
1836
|
+
/**
|
|
1837
|
+
* `app.game.diagnostics` — read what the player's caches are holding.
|
|
1838
|
+
*
|
|
1839
|
+
* The lightest of the list to grant and the easiest to misread as heavier than it is. Nothing
|
|
1840
|
+
* here is authored data: it reports how many images the engine is holding, how many bytes those
|
|
1841
|
+
* cost, and what budgets they are being held against. It reads no story, no save and no
|
|
1842
|
+
* variable, and every member is a read - there is nothing to set.
|
|
1843
|
+
*
|
|
1844
|
+
* It is its own capability rather than free like `data` and `config` because a plugin that
|
|
1845
|
+
* watches memory is a plugin that runs continuously and reports numbers about the player's
|
|
1846
|
+
* machine, and an author should see that named at install. The performance inspector is the
|
|
1847
|
+
* plugin this exists for.
|
|
1848
|
+
*
|
|
1849
|
+
* Absent until a game session is live, which is the same rule every other engine-backed member
|
|
1850
|
+
* follows: a plugin's `setup()` runs during boot, and asking then answers null rather than
|
|
1851
|
+
* throwing.
|
|
1852
|
+
*/
|
|
1853
|
+
readonly Diagnostics: "diagnostics";
|
|
2047
1854
|
};
|
|
2048
1855
|
type PluginRuntimeCapability = typeof PluginRuntimeCapability[keyof typeof PluginRuntimeCapability];
|
|
2049
1856
|
/**
|
|
@@ -2397,11 +2204,6 @@ export type RuntimePluginDescriptor = {
|
|
|
2397
2204
|
*/
|
|
2398
2205
|
buildConfig?: Record<string, string>;
|
|
2399
2206
|
};
|
|
2400
|
-
type GameProgressImportOutcome = {
|
|
2401
|
-
outcome: "found" | "missing" | "failed";
|
|
2402
|
-
sceneId: string;
|
|
2403
|
-
error: string;
|
|
2404
|
-
};
|
|
2405
2207
|
type GameMenuLabel = {
|
|
2406
2208
|
readonly key?: string | null;
|
|
2407
2209
|
readonly text: string;
|
|
@@ -2511,13 +2313,6 @@ type GameMenuSpecMenu = {
|
|
|
2511
2313
|
type GameMenuSpec = {
|
|
2512
2314
|
readonly menus: readonly GameMenuSpecMenu[];
|
|
2513
2315
|
};
|
|
2514
|
-
type UIInputActionSource = "pointer" | "key" | "gamepad" | "touch";
|
|
2515
|
-
type UIInputActionEventPayload = {
|
|
2516
|
-
actionId: string;
|
|
2517
|
-
source: UIInputActionSource;
|
|
2518
|
-
x?: number;
|
|
2519
|
-
y?: number;
|
|
2520
|
-
};
|
|
2521
2316
|
declare const UI_INPUT_POINTER_GESTURES: readonly [
|
|
2522
2317
|
"click",
|
|
2523
2318
|
"doubleClick",
|
|
@@ -2823,30 +2618,6 @@ type UILayout = {
|
|
|
2823
2618
|
lockAspectRatio?: boolean;
|
|
2824
2619
|
};
|
|
2825
2620
|
type UIStyle = Record<string, unknown>;
|
|
2826
|
-
type GameStorageDurability = "durable" | "evictable" | "unknown";
|
|
2827
|
-
type DevModeStartStoryRequest = {
|
|
2828
|
-
storyId: StoryId;
|
|
2829
|
-
sceneId: string;
|
|
2830
|
-
/** Row-precise "play from here": enter the game pre-posed at this block and play forward. */
|
|
2831
|
-
startBlockId?: string;
|
|
2832
|
-
/** Scene Snapshot (变量快照) whose variable overrides seed the launch. */
|
|
2833
|
-
snapshotId?: string;
|
|
2834
|
-
/**
|
|
2835
|
-
* Variable values lifted off a running game, laid over the launch's own stage walk.
|
|
2836
|
-
*
|
|
2837
|
-
* Set only by a hot reload resuming where the player was: the walk reconstructs what the values
|
|
2838
|
-
* would be had the story been played from the top down one path, and these are what they
|
|
2839
|
-
* actually were. Applied after the walk and after any Scene Snapshot, because they are the later
|
|
2840
|
-
* state - re-seeding either over them would rewind the player.
|
|
2841
|
-
*
|
|
2842
|
-
* Storage keys, the way the compiler names namespace entries, not variable ids. Persistent
|
|
2843
|
-
* values are absent by design: they outlive the run, so a reload has nothing to restore.
|
|
2844
|
-
*/
|
|
2845
|
-
resume?: {
|
|
2846
|
-
sceneVariables: Record<string, StoryLiteralValue>;
|
|
2847
|
-
savedVariables: Record<string, StoryLiteralValue>;
|
|
2848
|
-
};
|
|
2849
|
-
};
|
|
2850
2621
|
type GameTestLogLevel = "verbose" | "info" | "success" | "warning" | "error";
|
|
2851
2622
|
type GameTestExitReason =
|
|
2852
2623
|
/** Closed from inside the game - the window's own close, or the engine quitting itself. */
|
|
@@ -9680,6 +9451,10 @@ declare const en: {
|
|
|
9680
9451
|
};
|
|
9681
9452
|
readonly refs: "{count} refs";
|
|
9682
9453
|
};
|
|
9454
|
+
readonly canvas: {
|
|
9455
|
+
readonly unknownWidget: "Unknown widget";
|
|
9456
|
+
readonly widgetRenderFailed: "Widget failed to draw";
|
|
9457
|
+
};
|
|
9683
9458
|
readonly editor: {
|
|
9684
9459
|
readonly componentNotFound: "Component not found";
|
|
9685
9460
|
readonly interfaceNotFound: "Interface not found";
|
|
@@ -10524,6 +10299,7 @@ declare const en: {
|
|
|
10524
10299
|
readonly insert: "Insert {name}";
|
|
10525
10300
|
readonly drawing: "Drawing {name}: drag on canvas to create";
|
|
10526
10301
|
readonly moreInsertElements: "More insert elements";
|
|
10302
|
+
readonly fromPlugin: "From {plugin}";
|
|
10527
10303
|
readonly components: "Components";
|
|
10528
10304
|
readonly openComponentLibrary: "Open Component Library";
|
|
10529
10305
|
readonly componentLibrary: "Component Library";
|
|
@@ -11825,6 +11601,7 @@ declare const en: {
|
|
|
11825
11601
|
readonly locale: "Read the game language and the project's localized text";
|
|
11826
11602
|
readonly menu: "Provide the game's menu bar";
|
|
11827
11603
|
readonly storyCompile: "Take part in compiling stories, and add actions to lines it did not write";
|
|
11604
|
+
readonly diagnostics: "Read how much memory the game\u2019s caches are using";
|
|
11828
11605
|
};
|
|
11829
11606
|
};
|
|
11830
11607
|
readonly button: {
|
|
@@ -11936,6 +11713,25 @@ declare const en: {
|
|
|
11936
11713
|
readonly registry: "Failed to reach the plugin registry";
|
|
11937
11714
|
readonly download: "Failed to download plugin";
|
|
11938
11715
|
};
|
|
11716
|
+
readonly dependencies: {
|
|
11717
|
+
readonly title: "Project dependencies";
|
|
11718
|
+
readonly unavailable: {
|
|
11719
|
+
readonly one: "{count} plugin this project needs is not available.";
|
|
11720
|
+
readonly other: "{count} plugins this project needs are not available.";
|
|
11721
|
+
};
|
|
11722
|
+
readonly allReady: "Every plugin this project needs is available.";
|
|
11723
|
+
readonly open: "Open dependencies";
|
|
11724
|
+
readonly installAll: "Install all";
|
|
11725
|
+
readonly updated: "Updated";
|
|
11726
|
+
readonly authorized: "Authorized";
|
|
11727
|
+
readonly notInRegistry: "Not in the registry";
|
|
11728
|
+
readonly noCompatibleVersion: "No compatible version";
|
|
11729
|
+
readonly task: {
|
|
11730
|
+
readonly running: "Installing dependencies\u2026";
|
|
11731
|
+
readonly done: "Dependencies installed.";
|
|
11732
|
+
readonly partial: "Some plugins were not installed.";
|
|
11733
|
+
};
|
|
11734
|
+
};
|
|
11939
11735
|
readonly workspace: {
|
|
11940
11736
|
readonly reload: "Reload in this workspace";
|
|
11941
11737
|
readonly activity: {
|
|
@@ -11947,7 +11743,6 @@ declare const en: {
|
|
|
11947
11743
|
readonly suppressedHint: "The installed version is incompatible with the one this project was authored against. Update it, or update the project's dependency table from Project \u25B8 App.";
|
|
11948
11744
|
readonly failed: "Failed to load";
|
|
11949
11745
|
};
|
|
11950
|
-
readonly suppressedNotice: "Not loaded for this project: {names}. The installed version is incompatible with the one the project was authored against. See the Plugins panel.";
|
|
11951
11746
|
readonly pendingReopen: "Takes effect the next time this project opens.";
|
|
11952
11747
|
readonly restartHint: "Some plugin changes take effect only after the workspace is restarted.";
|
|
11953
11748
|
readonly restart: "Restart";
|
|
@@ -12886,6 +12681,11 @@ declare const en: {
|
|
|
12886
12681
|
readonly description: "A clickable widget nothing listens to";
|
|
12887
12682
|
readonly message: "Nothing runs when this is clicked";
|
|
12888
12683
|
};
|
|
12684
|
+
readonly uiUnknownWidget: {
|
|
12685
|
+
readonly title: "Unknown widget type";
|
|
12686
|
+
readonly description: "A widget whose type the project cannot load";
|
|
12687
|
+
readonly message: "{type} is not loaded, so this widget will not be drawn in the game";
|
|
12688
|
+
};
|
|
12889
12689
|
readonly uiComponentMissing: {
|
|
12890
12690
|
readonly title: "Missing component";
|
|
12891
12691
|
readonly description: "An instance of a component the project does not have";
|
|
@@ -14818,26 +14618,6 @@ export declare const AssetExtensions: {
|
|
|
14818
14618
|
model: string[];
|
|
14819
14619
|
other: string[];
|
|
14820
14620
|
};
|
|
14821
|
-
type BlueprintVector2D = {
|
|
14822
|
-
x: number;
|
|
14823
|
-
y: number;
|
|
14824
|
-
};
|
|
14825
|
-
type BlueprintRect = {
|
|
14826
|
-
x: number;
|
|
14827
|
-
y: number;
|
|
14828
|
-
width: number;
|
|
14829
|
-
height: number;
|
|
14830
|
-
};
|
|
14831
|
-
type BlueprintRGBAColor = {
|
|
14832
|
-
r: number;
|
|
14833
|
-
g: number;
|
|
14834
|
-
b: number;
|
|
14835
|
-
a: number;
|
|
14836
|
-
};
|
|
14837
|
-
type BlueprintImageAsset = {
|
|
14838
|
-
kind: "imageAsset";
|
|
14839
|
-
assetId: string;
|
|
14840
|
-
};
|
|
14841
14621
|
type BlueprintAssetPinKind = "image" | "audio" | "font";
|
|
14842
14622
|
type BlueprintAssetPinRef = {
|
|
14843
14623
|
kind: BlueprintAssetPinKind;
|
|
@@ -14856,10 +14636,6 @@ type BlueprintAssetPinRef = {
|
|
|
14856
14636
|
*/
|
|
14857
14637
|
origin?: "stored" | "published";
|
|
14858
14638
|
};
|
|
14859
|
-
type BlueprintSoundHandle = {
|
|
14860
|
-
kind: "soundHandle";
|
|
14861
|
-
id: string;
|
|
14862
|
-
};
|
|
14863
14639
|
interface ProjectProps {
|
|
14864
14640
|
projectPath: string;
|
|
14865
14641
|
}
|
|
@@ -15895,33 +15671,6 @@ type UIElementSelection = {
|
|
|
15895
15671
|
elementIds: UIElementId[];
|
|
15896
15672
|
primaryId?: UIElementId;
|
|
15897
15673
|
};
|
|
15898
|
-
type GradientKind = "linear" | "radial" | "conic";
|
|
15899
|
-
interface GradientStop {
|
|
15900
|
-
/** 0..1 along the gradient line. */
|
|
15901
|
-
offset: number;
|
|
15902
|
-
/**
|
|
15903
|
-
* A stored colour string: a literal, or `nlbrand:<id>[/<alpha>]`. Deliberately unresolved - see
|
|
15904
|
-
* the file comment.
|
|
15905
|
-
*/
|
|
15906
|
-
color: string;
|
|
15907
|
-
}
|
|
15908
|
-
interface GradientFill {
|
|
15909
|
-
kind: GradientKind;
|
|
15910
|
-
/** Normalised to two or more, sorted by offset, offsets clamped to 0..1. */
|
|
15911
|
-
stops: GradientStop[];
|
|
15912
|
-
/** Linear and conic. Degrees, CSS convention: 0 points to the top, 90 to the right. */
|
|
15913
|
-
angle?: number;
|
|
15914
|
-
/** Radial and conic. 0..1 of the painted box. */
|
|
15915
|
-
center?: {
|
|
15916
|
-
x: number;
|
|
15917
|
-
y: number;
|
|
15918
|
-
};
|
|
15919
|
-
/** Radial. 0..1 of the painted box, one radius per axis. */
|
|
15920
|
-
radius?: {
|
|
15921
|
-
x: number;
|
|
15922
|
-
y: number;
|
|
15923
|
-
};
|
|
15924
|
-
}
|
|
15925
15674
|
type ImageFillMode = "cover" | "contain" | "stretch" | "crop" | "tile";
|
|
15926
15675
|
interface ImageFillCropPlacement {
|
|
15927
15676
|
leftPct: number;
|
|
@@ -15956,1030 +15705,97 @@ type UIListItemScope = {
|
|
|
15956
15705
|
*/
|
|
15957
15706
|
struct?: UIStructDef | null;
|
|
15958
15707
|
};
|
|
15959
|
-
type
|
|
15960
|
-
|
|
15961
|
-
|
|
15962
|
-
|
|
15963
|
-
};
|
|
15964
|
-
declare const BLUEPRINT_HOST_API_CONTRACT_VERSION: 39;
|
|
15965
|
-
type BlueprintHostApiContractVersion = typeof BLUEPRINT_HOST_API_CONTRACT_VERSION;
|
|
15966
|
-
type BlueprintCharacterInfo = {
|
|
15967
|
-
id: string;
|
|
15968
|
-
/** Author-facing display name. Empty when the character is unnamed - never falls back to `id`, which is a UUID. */
|
|
15969
|
-
name: string;
|
|
15970
|
-
/**
|
|
15971
|
-
* The author's accent colour, already in pin shape. Null when the character has no colour set,
|
|
15972
|
-
* which is a different thing from "white" - see {@link blueprintCharacterColorOrDefault} for
|
|
15973
|
-
* what a non-nullable colour pin does with it.
|
|
15974
|
-
*/
|
|
15975
|
-
color: BlueprintRGBAColor | null;
|
|
15976
|
-
/** The character's default dialog avatar, or null when it has none. */
|
|
15977
|
-
avatar: BlueprintImageAsset | null;
|
|
15978
|
-
};
|
|
15979
|
-
type AppearanceSystemCondition = Partial<{
|
|
15980
|
-
hovered: boolean;
|
|
15981
|
-
active: boolean;
|
|
15982
|
-
disabled: boolean;
|
|
15983
|
-
focused: boolean;
|
|
15984
|
-
/** Inside the row a list has selected. */
|
|
15985
|
-
selected: boolean;
|
|
15986
|
-
}>;
|
|
15987
|
-
type AppearanceRowValue = string | number | boolean | null | ImageFill | GradientFill | Record<string, unknown>;
|
|
15988
|
-
type AppearanceValueRow = {
|
|
15989
|
-
conditions?: AppearanceSystemCondition | null;
|
|
15990
|
-
value: AppearanceRowValue;
|
|
15991
|
-
};
|
|
15992
|
-
type AppearanceTransitionTweenEasing = "linear" | "easeIn" | "easeOut" | "easeInOut" | "circIn" | "circOut" | "circInOut";
|
|
15993
|
-
type AppearanceFieldTransition = {
|
|
15994
|
-
type: "tween";
|
|
15995
|
-
durationMs: number;
|
|
15996
|
-
delayMs?: number;
|
|
15997
|
-
easing: AppearanceTransitionTweenEasing;
|
|
15998
|
-
} | {
|
|
15999
|
-
type: "spring";
|
|
16000
|
-
delayMs?: number;
|
|
16001
|
-
stiffness: number;
|
|
16002
|
-
damping: number;
|
|
16003
|
-
mass: number;
|
|
16004
|
-
};
|
|
16005
|
-
type ContainerAppearancePropertyKey = "backgroundColor" | "borderRadius" | "borderRadiusTL" | "borderRadiusTR" | "borderRadiusBL" | "borderRadiusBR" | "borderRadiusLinked" | "borderColor" | "borderWidth" | "borderStyle" | "backgroundImage" | "backgroundFit" | "imageFill" | "gradientFill" | "fillType" | "fillVisible" | "fillOpacity" | "strokeVisible" | "strokeOpacity" | "strokeAlign" | "strokeSide" | "borderJoin" | "cornerAdvanced" | "transformOffsetX" | "transformOffsetY" | "transformScale" | "transformRotation" | "transformOpacity" | "effectBlur" | "effectBackgroundBlur" | "effectShadow" | "effectInnerShadow" | "effectBlend" | "effectGlow" | "effectFilter";
|
|
16006
|
-
declare const BUTTON_CURSOR_VALUES: readonly [
|
|
16007
|
-
"auto",
|
|
16008
|
-
"default",
|
|
16009
|
-
"pointer",
|
|
16010
|
-
"text",
|
|
16011
|
-
"move",
|
|
16012
|
-
"grab",
|
|
16013
|
-
"grabbing",
|
|
16014
|
-
"crosshair",
|
|
16015
|
-
"help",
|
|
16016
|
-
"wait",
|
|
16017
|
-
"progress",
|
|
16018
|
-
"not-allowed"
|
|
16019
|
-
];
|
|
16020
|
-
type ButtonCursorValue = (typeof BUTTON_CURSOR_VALUES)[number];
|
|
16021
|
-
type ButtonAppearancePropertyKey = "fontAssetId" | "fontSize" | "fontWeight" | "color" | "lineHeight" | "backgroundColor" | "fillType" | "fillOpacity" | "fillVisible" | "imageFill" | "gradientFill" | "backgroundImage" | "backgroundFit" | "borderRadius" | "borderWidth" | "borderColor" | "borderStyle" | "strokeOpacity" | "strokeSide" | "borderJoin" | "strokeAlign" | "paddingX" | "paddingY" | "clipContent" | "cursor" | "transformOffsetX" | "transformOffsetY" | "transformScale" | "transformRotation" | "transformOpacity" | "effectBlur" | "effectBackgroundBlur" | "effectShadow" | "effectTextShadow" | "effectInnerShadow" | "effectBlend" | "effectGlow" | "effectFilter";
|
|
16022
|
-
type TextAppearancePropertyKey = "fontAssetId" | "fontSize" | "fontWeight" | "fontStyle" | "color" | "lineHeight" | "transformOffsetX" | "transformOffsetY" | "transformScale" | "transformRotation" | "transformOpacity" | "effectBlur" | "effectTextShadow" | "effectBlend" | "effectFilter";
|
|
16023
|
-
type AppearancePropertyGroup = {
|
|
16024
|
-
key: ContainerAppearancePropertyKey;
|
|
16025
|
-
rows: AppearanceValueRow[];
|
|
16026
|
-
transition?: AppearanceFieldTransition | null;
|
|
16027
|
-
} | {
|
|
16028
|
-
key: ButtonAppearancePropertyKey;
|
|
16029
|
-
rows: AppearanceValueRow[];
|
|
16030
|
-
transition?: AppearanceFieldTransition | null;
|
|
16031
|
-
} | {
|
|
16032
|
-
key: TextAppearancePropertyKey;
|
|
16033
|
-
rows: AppearanceValueRow[];
|
|
16034
|
-
transition?: AppearanceFieldTransition | null;
|
|
16035
|
-
};
|
|
16036
|
-
type AppearanceVariant = {
|
|
16037
|
-
id: string;
|
|
16038
|
-
name: string;
|
|
16039
|
-
propertyGroups: AppearancePropertyGroup[];
|
|
16040
|
-
};
|
|
16041
|
-
type AppearanceModel = {
|
|
16042
|
-
defaultVariantId: string;
|
|
16043
|
-
variants: AppearanceVariant[];
|
|
16044
|
-
};
|
|
16045
|
-
type UISliderOrientation = "horizontal" | "vertical";
|
|
16046
|
-
type UISliderWidgetProps = {
|
|
16047
|
-
value: number;
|
|
16048
|
-
min: number;
|
|
16049
|
-
max: number;
|
|
16050
|
-
step: number;
|
|
16051
|
-
orientation: UISliderOrientation;
|
|
16052
|
-
trackElementId?: string | null;
|
|
16053
|
-
handleElementId?: string | null;
|
|
16054
|
-
};
|
|
16055
|
-
type UISliderRange = {
|
|
16056
|
-
min: number;
|
|
16057
|
-
max: number;
|
|
16058
|
-
step: number;
|
|
16059
|
-
};
|
|
16060
|
-
type UISliderRuntimeValue = UISliderRange & {
|
|
16061
|
-
value: number;
|
|
16062
|
-
normalizedValue: number;
|
|
16063
|
-
};
|
|
16064
|
-
type UISwitchWidgetProps = {
|
|
16065
|
-
/** The author's starting state. What the player toggles lives in WidgetRuntimeStateStore. */
|
|
16066
|
-
checked: boolean;
|
|
16067
|
-
/** Blocks pointer and keyboard toggling. Looks are the `disabled` appearance signal's job. */
|
|
16068
|
-
interactionDisabled: boolean;
|
|
16069
|
-
trackElementId?: string | null;
|
|
16070
|
-
thumbElementId?: string | null;
|
|
16071
|
-
};
|
|
16072
|
-
type UISwitchRuntimeValue = {
|
|
16073
|
-
checked: boolean;
|
|
16074
|
-
};
|
|
16075
|
-
type UITextInputMode = "text" | "password" | "number";
|
|
16076
|
-
type UITextInputWidgetProps = {
|
|
16077
|
-
value: string;
|
|
16078
|
-
placeholder: string;
|
|
16079
|
-
/** i18n attach-layer key for `placeholder`; player-facing text is never a Studio catalog key. */
|
|
16080
|
-
placeholderLocalizationKey?: string | null;
|
|
16081
|
-
inputMode: UITextInputMode;
|
|
16082
|
-
/** 0 = unlimited. */
|
|
16083
|
-
maxLength: number;
|
|
16084
|
-
readOnly: boolean;
|
|
16085
|
-
disabled: boolean;
|
|
16086
|
-
textAlign: "left" | "center" | "right";
|
|
16087
|
-
};
|
|
16088
|
-
type UITextInputRuntimeValue = {
|
|
16089
|
-
value: string;
|
|
16090
|
-
/** Length in code points, so an emoji counts once - this is what `maxLength` is measured in. */
|
|
16091
|
-
length: number;
|
|
16092
|
-
};
|
|
16093
|
-
type UIDisplayableMotionFromCurrentValue = {
|
|
16094
|
-
from: "current";
|
|
16095
|
-
to: number;
|
|
16096
|
-
};
|
|
16097
|
-
type UIDisplayableMotionValue = number | number[] | UIDisplayableMotionFromCurrentValue;
|
|
16098
|
-
type UIDisplayableMotionTarget = {
|
|
16099
|
-
x?: UIDisplayableMotionValue;
|
|
16100
|
-
y?: UIDisplayableMotionValue;
|
|
16101
|
-
scale?: UIDisplayableMotionValue;
|
|
16102
|
-
rotate?: UIDisplayableMotionValue;
|
|
16103
|
-
opacity?: UIDisplayableMotionValue;
|
|
16104
|
-
};
|
|
16105
|
-
type UIDisplayableMotionTransition = {
|
|
16106
|
-
type: "tween";
|
|
16107
|
-
durationMs: number;
|
|
16108
|
-
delayMs?: number;
|
|
16109
|
-
easing?: string;
|
|
16110
|
-
} | {
|
|
16111
|
-
type: "spring";
|
|
16112
|
-
delayMs?: number;
|
|
16113
|
-
stiffness: number;
|
|
16114
|
-
damping: number;
|
|
16115
|
-
mass: number;
|
|
16116
|
-
};
|
|
16117
|
-
type UIDisplayableMotionOverride = {
|
|
16118
|
-
id: string;
|
|
16119
|
-
target: UIDisplayableMotionTarget;
|
|
16120
|
-
transition: UIDisplayableMotionTransition;
|
|
16121
|
-
/** One-shot effects such as shake/pulse should hand control back to authored layout when finished. */
|
|
16122
|
-
resetOnComplete?: boolean;
|
|
16123
|
-
};
|
|
16124
|
-
type TextWritingMode = NlrTextWritingMode;
|
|
16125
|
-
type TextOrientation = TextGlyphOrientation;
|
|
16126
|
-
type UITextRunMarks = Pick<StoryTextMarks, "bold" | "italic" | "color" | "ruby" | "fontSizeStep" | "emphasis">;
|
|
16127
|
-
type UITextRun = {
|
|
16128
|
-
text: string;
|
|
16129
|
-
marks?: UITextRunMarks;
|
|
16130
|
-
};
|
|
16131
|
-
type EffectShadowLayerData = {
|
|
16132
|
-
offsetX: number;
|
|
16133
|
-
offsetY: number;
|
|
16134
|
-
blur: number;
|
|
16135
|
-
spread: number;
|
|
16136
|
-
color: string;
|
|
16137
|
-
};
|
|
16138
|
-
type FilterPresetId = "brightness" | "contrast" | "saturate" | "grayscale";
|
|
16139
|
-
type EffectShadowLayer = EffectShadowLayerData;
|
|
16140
|
-
type EffectShadowStored = {
|
|
16141
|
-
storage: "layer";
|
|
16142
|
-
layer: EffectShadowLayer;
|
|
16143
|
-
} | {
|
|
16144
|
-
storage: "css";
|
|
16145
|
-
css: string;
|
|
16146
|
-
};
|
|
16147
|
-
type EffectFilterStored = {
|
|
16148
|
-
storage: "preset";
|
|
16149
|
-
preset: FilterPresetId;
|
|
16150
|
-
amount: number;
|
|
16151
|
-
} | {
|
|
16152
|
-
storage: "css";
|
|
16153
|
-
css: string;
|
|
16154
|
-
};
|
|
16155
|
-
type ElementEffectValues = {
|
|
16156
|
-
effectBlur: number;
|
|
16157
|
-
effectBackgroundBlur: number;
|
|
16158
|
-
effectShadow: EffectShadowStored | null;
|
|
16159
|
-
/** Text widgets: CSS text-shadow (separate from box-shadow `effectShadow`). */
|
|
16160
|
-
effectTextShadow: EffectShadowStored | null;
|
|
16161
|
-
effectInnerShadow: EffectShadowStored | null;
|
|
16162
|
-
effectBlend: string;
|
|
16163
|
-
effectGlow: EffectShadowStored | null;
|
|
16164
|
-
effectFilter: EffectFilterStored | null;
|
|
16165
|
-
};
|
|
16166
|
-
type TextAlign = "left" | "center" | "right";
|
|
16167
|
-
type TextVerticalAlign = "start" | "center" | "end";
|
|
16168
|
-
type TextWrapMode = "word" | "character" | "nowrap";
|
|
16169
|
-
type TextWidgetProps = {
|
|
16170
|
-
text: string;
|
|
16171
|
-
/**
|
|
16172
|
-
* The label's text as marked runs, when it carries any.
|
|
16173
|
-
*
|
|
16174
|
-
* `text` stays the plain string and stays what everything else reads - a value binding writes
|
|
16175
|
-
* it, a translation replaces it, a plain field edits it - and these runs are only drawn while
|
|
16176
|
-
* they still spell it (`resolveUITextRuns`). Absent on every label that has never been marked,
|
|
16177
|
-
* which is what keeps the drawing of a plain label exactly what it was.
|
|
16178
|
-
*/
|
|
16179
|
-
rich?: UITextRun[];
|
|
16180
|
-
/** Game-localization opt-in: registers the implicit translation unit `ui:<elementId>.text`. */
|
|
16181
|
-
localizable?: boolean;
|
|
16182
|
-
/** Named localization key reference; takes precedence over the implicit unit. */
|
|
16183
|
-
localizationKey?: string;
|
|
16184
|
-
fontSize: number;
|
|
16185
|
-
color: string;
|
|
16186
|
-
fontWeight: "normal" | "bold" | "600";
|
|
16187
|
-
fontStyle: "normal" | "italic";
|
|
16188
|
-
textAlign: TextAlign;
|
|
16189
|
-
textVerticalAlign: TextVerticalAlign;
|
|
16190
|
-
lineHeight: number;
|
|
16191
|
-
/** Project font asset id when using a custom typeface in the editor; null inherits canvas default */
|
|
16192
|
-
fontAssetId: string | null;
|
|
16193
|
-
textWrapMode: TextWrapMode;
|
|
16194
|
-
/**
|
|
16195
|
-
* Shrink the rendered text until it fits the element's box.
|
|
16196
|
-
*
|
|
16197
|
-
* The authored `fontSize` becomes a ceiling rather than a fixed value: the text is never set
|
|
16198
|
-
* larger than it, and never smaller than {@link TextWidgetProps.textAutoFitMinFontSize}. A line
|
|
16199
|
-
* that still does not fit at the floor is clipped, which is what every line does today.
|
|
16200
|
-
*/
|
|
16201
|
-
textAutoFit: boolean;
|
|
16202
|
-
/** Smallest size auto fit may set, in px. */
|
|
16203
|
-
textAutoFitMinFontSize: number;
|
|
16204
|
-
/** Block flow. `horizontal-tb` leaves every other vertical setting inert. */
|
|
16205
|
-
writingMode: TextWritingMode;
|
|
16206
|
-
textOrientation: TextOrientation;
|
|
16207
|
-
/**
|
|
16208
|
-
* 縦中横: sets a short Latin or digit run upright across the column instead of on its side,
|
|
16209
|
-
* the way a Japanese novel sets a two-digit number. Only read while writing vertically.
|
|
16210
|
-
*/
|
|
16211
|
-
tateChuYoko: boolean;
|
|
16212
|
-
/** Longest run tate-chu-yoko combines, in characters. Two is the typographic convention. */
|
|
16213
|
-
tateChuYokoMaxLength: number;
|
|
16214
|
-
transformOffsetX: number;
|
|
16215
|
-
transformOffsetY: number;
|
|
16216
|
-
transformScale: number;
|
|
16217
|
-
transformRotation: number;
|
|
16218
|
-
transformOpacity: number;
|
|
16219
|
-
/** Static baseline effects; appearance overlays may override per variant / state. */
|
|
16220
|
-
effects: ElementEffectValues;
|
|
16221
|
-
/** Optional variant + conditional row visuals; when absent, flat props are the sole source. */
|
|
16222
|
-
appearance?: AppearanceModel | null;
|
|
16223
|
-
};
|
|
16224
|
-
type BlueprintPointerMoveOptions = {
|
|
16225
|
-
durationSeconds?: number;
|
|
16226
|
-
easing?: BlueprintPointerMoveEasing;
|
|
16227
|
-
};
|
|
16228
|
-
type BlueprintTextProperties = Pick<TextWidgetProps, "text" | "fontAssetId" | "fontSize" | "fontWeight" | "color" | "textAlign" | "textVerticalAlign" | "lineHeight" | "textWrapMode" | "effects">;
|
|
16229
|
-
type BlueprintTextPropertiesPatch = Partial<BlueprintTextProperties>;
|
|
16230
|
-
type BlueprintSliderProperties = UISliderRuntimeValue;
|
|
16231
|
-
type BlueprintSliderPropertiesPatch = Partial<Pick<UISliderWidgetProps, "value" | "min" | "max" | "step">>;
|
|
16232
|
-
type BlueprintSwitchProperties = UISwitchRuntimeValue;
|
|
16233
|
-
type BlueprintSwitchPropertiesPatch = Partial<Pick<UISwitchWidgetProps, "checked">>;
|
|
16234
|
-
type BlueprintTextInputProperties = UITextInputRuntimeValue;
|
|
16235
|
-
type BlueprintTextInputPropertiesPatch = Partial<Pick<UITextInputWidgetProps, "value">>;
|
|
16236
|
-
type BlueprintListProperties = {
|
|
16237
|
-
items: unknown[];
|
|
16238
|
-
selectedIndex: number;
|
|
16239
|
-
/**
|
|
16240
|
-
* The shape the list declares, or null when it declares none.
|
|
16241
|
-
*
|
|
16242
|
-
* Carried with the items rather than fetched separately, because every node that reads a field
|
|
16243
|
-
* needs both and reading them apart is how the two drift: a graph that sorted by a field the
|
|
16244
|
-
* list no longer declares would sort by nothing and report success.
|
|
16245
|
-
*/
|
|
16246
|
-
struct: UIStructDef | null;
|
|
16247
|
-
/**
|
|
16248
|
-
* Where the list has got to along its axis, as it last measured itself.
|
|
16249
|
-
*
|
|
16250
|
-
* A list that has not been rendered - or has been rendered somewhere with no runtime store, like
|
|
16251
|
-
* a Surface thumbnail - reports at-rest rather than nothing, so a graph asking gets the answer
|
|
16252
|
-
* for a list that cannot scroll instead of an undefined it has no way to branch on.
|
|
16253
|
-
*/
|
|
16254
|
-
scroll: UIListScrollMetrics;
|
|
16255
|
-
};
|
|
16256
|
-
type BlueprintDisplayableProperties = {
|
|
16257
|
-
position: {
|
|
16258
|
-
x: number;
|
|
16259
|
-
y: number;
|
|
16260
|
-
};
|
|
16261
|
-
offset: {
|
|
16262
|
-
x: number;
|
|
16263
|
-
y: number;
|
|
16264
|
-
};
|
|
16265
|
-
/**
|
|
16266
|
-
* The extent the widget covers, never negative. The authored layout may hold a negative width
|
|
16267
|
-
* or height - that is how a widget dragged past its own origin is stored - and `position`
|
|
16268
|
-
* already reports the true top-left, so reporting the raw sign here would have described a
|
|
16269
|
-
* rectangle whose right edge sits left of its left edge.
|
|
16270
|
-
*/
|
|
16271
|
-
size: {
|
|
16272
|
-
width: number;
|
|
16273
|
-
height: number;
|
|
16274
|
-
};
|
|
16275
|
-
bounds: BlueprintRect;
|
|
16276
|
-
rotation: number;
|
|
16277
|
-
opacity: number;
|
|
16278
|
-
display: boolean;
|
|
16279
|
-
visible: boolean;
|
|
16280
|
-
};
|
|
16281
|
-
type BlueprintDisplayablePropertiesPatch = Partial<{
|
|
16282
|
-
x: number;
|
|
16283
|
-
y: number;
|
|
16284
|
-
offsetX: number;
|
|
16285
|
-
offsetY: number;
|
|
16286
|
-
width: number;
|
|
16287
|
-
height: number;
|
|
16288
|
-
rotation: number;
|
|
16289
|
-
opacity: number;
|
|
16290
|
-
display: boolean;
|
|
16291
|
-
visible: boolean;
|
|
16292
|
-
}>;
|
|
16293
|
-
type BlueprintDisplayableMotionRequest = {
|
|
16294
|
-
id?: string;
|
|
16295
|
-
target: UIDisplayableMotionTarget;
|
|
16296
|
-
transition: UIDisplayableMotionTransition;
|
|
16297
|
-
resetOnComplete?: boolean;
|
|
16298
|
-
commitLayoutOnComplete?: Partial<Pick<BlueprintDisplayablePropertiesPatch, "x" | "y">>;
|
|
16299
|
-
};
|
|
16300
|
-
type BlueprintWidgetCommonProperties = {
|
|
16301
|
-
visible: boolean;
|
|
16302
|
-
enabled: boolean;
|
|
16303
|
-
variantId: string | null;
|
|
16304
|
-
};
|
|
16305
|
-
type BlueprintButtonProperties = {
|
|
16306
|
-
label: string;
|
|
16307
|
-
cursor: ButtonCursorValue;
|
|
16308
|
-
};
|
|
16309
|
-
type BlueprintContainerProperties = {
|
|
16310
|
-
clipContent: boolean;
|
|
15708
|
+
type BehaviorNodeExecuteResult = {
|
|
15709
|
+
nextPort?: string;
|
|
15710
|
+
nextPorts?: string[];
|
|
15711
|
+
outputValues?: Record<string, unknown>;
|
|
16311
15712
|
};
|
|
16312
|
-
type
|
|
16313
|
-
|
|
16314
|
-
|
|
16315
|
-
|
|
16316
|
-
|
|
16317
|
-
|
|
16318
|
-
|
|
16319
|
-
flipY: boolean;
|
|
15713
|
+
type StoryBlockSelection = {
|
|
15714
|
+
editor: "story";
|
|
15715
|
+
tabId: string;
|
|
15716
|
+
storyId: StoryId;
|
|
15717
|
+
sceneId: StorySceneId;
|
|
15718
|
+
/** The focused row, or null when the scene itself is the subject. */
|
|
15719
|
+
blockId: StoryBlockId | null;
|
|
16320
15720
|
};
|
|
16321
|
-
type
|
|
16322
|
-
|
|
16323
|
-
|
|
15721
|
+
type StoryMotionKeyframeSelection = {
|
|
15722
|
+
editor: "story-motion";
|
|
15723
|
+
tabId: string;
|
|
15724
|
+
animationId: string;
|
|
15725
|
+
trackId: string;
|
|
15726
|
+
keyframeId: string;
|
|
16324
15727
|
};
|
|
16325
|
-
type
|
|
15728
|
+
type ComparisonHalf = "base" | "head";
|
|
15729
|
+
interface ComparisonElementSelection {
|
|
15730
|
+
/** Repository-relative path of the document being compared. Identity, not a read address. */
|
|
15731
|
+
readonly documentPath: string;
|
|
15732
|
+
readonly half: ComparisonHalf;
|
|
15733
|
+
/** What that half calls its version, already resolved to text by the tab that knows. */
|
|
15734
|
+
readonly versionLabel: string;
|
|
15735
|
+
/** What the OTHER half calls its version. The strip names it when the element is not in it. */
|
|
15736
|
+
readonly counterpartLabel: string;
|
|
15737
|
+
readonly surfaceId: string;
|
|
15738
|
+
readonly elementId: string;
|
|
15739
|
+
/** The element, out of that half's parsed document. */
|
|
15740
|
+
readonly element: UIElement;
|
|
15741
|
+
/** That half's whole document, so a field can resolve a parent, a component or a binding. */
|
|
15742
|
+
readonly document: UIDocument;
|
|
15743
|
+
/** The same element in the other half, or null when that half does not hold it. */
|
|
15744
|
+
readonly counterpart: UIElement | null;
|
|
15745
|
+
/** The other half's document, for the fields that read one. Null when there is no other half. */
|
|
15746
|
+
readonly counterpartDocument: UIDocument | null;
|
|
15747
|
+
}
|
|
16326
15748
|
/**
|
|
16327
|
-
*
|
|
15749
|
+
* What a plugin may add to Studio's built-in text editor.
|
|
15750
|
+
*
|
|
15751
|
+
* Studio ships the editor and nothing on top of it: no Markdown preview, no lint, no formatter.
|
|
15752
|
+
* Those are plugin work, and this module is the whole of what a plugin needs to do them - a
|
|
15753
|
+
* grammar, a preview pane, a command. The host registry is
|
|
15754
|
+
* `TextEditorContributionService`; the plugin-facing names are re-exported from
|
|
15755
|
+
* `@/plugin` and published in the `narraleaf-studio` types package.
|
|
15756
|
+
*
|
|
15757
|
+
* Two rules the rest of the design follows from:
|
|
16328
15758
|
*
|
|
16329
|
-
*
|
|
16330
|
-
*
|
|
16331
|
-
*
|
|
15759
|
+
* - **Imperative, not declarative.** There is no `contributes.textEditor` manifest key, for the
|
|
15760
|
+
* same reason `ui.panels` has none: nothing outside the editor session needs to know these
|
|
15761
|
+
* exist, so a static declaration would be bookkeeping with no reader.
|
|
15762
|
+
* - **Nothing is rendered for an empty registry.** A preview toggle with no preview behind it is
|
|
15763
|
+
* a dead control, and the editor's status bar is values-only by design. The consumer shows the
|
|
15764
|
+
* toggles for the previews that match *this* document's extension and nothing otherwise.
|
|
16332
15765
|
*/
|
|
16333
|
-
|
|
15766
|
+
/** The character encoding a document is currently being read and written in. */
|
|
15767
|
+
export type PluginTextEditorEncodingId = TextEncodingId;
|
|
16334
15768
|
/**
|
|
16335
|
-
*
|
|
16336
|
-
*
|
|
15769
|
+
* A Monarch grammar - monaco's `languages.IMonarchLanguage`.
|
|
15770
|
+
*
|
|
15771
|
+
* Typed structurally rather than by importing monaco's declarations: the published
|
|
15772
|
+
* `narraleaf-studio` types package would otherwise have to carry monaco's entire `.d.ts` surface,
|
|
15773
|
+
* and a plugin would need monaco installed to write a twenty-line grammar. The host casts on the
|
|
15774
|
+
* way into `monaco.languages.setMonarchTokensProvider`.
|
|
16337
15775
|
*/
|
|
16338
|
-
|
|
15776
|
+
export type PluginTextEditorMonarchGrammar = {
|
|
15777
|
+
tokenizer: Record<string, unknown>;
|
|
15778
|
+
[key: string]: unknown;
|
|
15779
|
+
};
|
|
15780
|
+
/** A monaco `languages.LanguageConfiguration` (comments, brackets, auto-closing pairs, folding). */
|
|
15781
|
+
export type PluginTextEditorLanguageConfiguration = Record<string, unknown>;
|
|
16339
15782
|
/**
|
|
16340
|
-
*
|
|
16341
|
-
*
|
|
16342
|
-
*
|
|
15783
|
+
* A language the built-in editor should colour.
|
|
15784
|
+
*
|
|
15785
|
+
* Registered into monaco **lazily** - the first time a document with one of these extensions is
|
|
15786
|
+
* opened, not when the plugin's `setup` runs. Monaco is a large module that Studio loads on the
|
|
15787
|
+
* first text tab and never before; a language registration at setup time would drag it into
|
|
15788
|
+
* startup for every workspace, whether or not a text file is ever opened.
|
|
16343
15789
|
*/
|
|
16344
|
-
|
|
16345
|
-
/**
|
|
16346
|
-
|
|
16347
|
-
|
|
16348
|
-
|
|
16349
|
-
|
|
16350
|
-
|
|
16351
|
-
|
|
16352
|
-
|
|
16353
|
-
type BlueprintGamePreferenceValue = boolean | number | BlueprintGamePreferenceVoiceEndMode;
|
|
16354
|
-
type BlueprintLayerShowOptions = {
|
|
16355
|
-
/** Everything below goes inert and the keys belong to this layer. */
|
|
16356
|
-
modal?: boolean;
|
|
16357
|
-
/** Whether Go back closes it. Default true. */
|
|
16358
|
-
dismissible?: boolean;
|
|
16359
|
-
/** Mutual-exclusion group; a second layer of an occupied group queues behind the first. */
|
|
16360
|
-
group?: string | null;
|
|
16361
|
-
};
|
|
16362
|
-
type BlueprintHostApiRuntime = {
|
|
16363
|
-
navigation: {
|
|
16364
|
-
openSurface: (surfaceId: string, props?: unknown) => Promise<void>;
|
|
16365
|
-
getPageProps: () => Record<string, unknown>;
|
|
16366
|
-
pageBack: () => Promise<void>;
|
|
16367
|
-
clearPages: () => Promise<void>;
|
|
16368
|
-
clearGameOverlay: () => Promise<void>;
|
|
16369
|
-
quitApplication: () => Promise<void>;
|
|
16370
|
-
getFullscreen: () => Promise<boolean>;
|
|
16371
|
-
setFullscreen: (fullscreen: boolean) => Promise<void>;
|
|
16372
|
-
/** The sizes worth offering, ascending. Empty where the shell has no window to size. */
|
|
16373
|
-
getWindowScaleOptions: () => Promise<number[]>;
|
|
16374
|
-
getWindowScale: () => Promise<number>;
|
|
16375
|
-
setWindowScale: (scale: number) => Promise<void>;
|
|
16376
|
-
getWindowSize: () => Promise<{
|
|
16377
|
-
width: number;
|
|
16378
|
-
height: number;
|
|
16379
|
-
}>;
|
|
16380
|
-
setWindowSize: (width: number, height: number) => Promise<void>;
|
|
16381
|
-
/**
|
|
16382
|
-
* Open one web address in the player's browser.
|
|
16383
|
-
*
|
|
16384
|
-
* The host does not decide: it hands the request to whatever the shell supplied, and the
|
|
16385
|
-
* shell's own process checks it against the addresses the build declared. Nothing here
|
|
16386
|
-
* consults the project's network setting, because no request is made - see
|
|
16387
|
-
* `@shared/types/blueprint/externalLink`.
|
|
16388
|
-
*/
|
|
16389
|
-
openExternal: (request: BlueprintOpenExternalRequest) => Promise<BlueprintOpenExternalResult>;
|
|
16390
|
-
/**
|
|
16391
|
-
* Write a picture of the frame the player is looking at, and say where it went.
|
|
16392
|
-
*
|
|
16393
|
-
* The shell decides where: a path chosen in a graph would be a path a graph could write
|
|
16394
|
-
* anywhere the player's account can. See `@shared/types/blueprint/screenshot`.
|
|
16395
|
-
*/
|
|
16396
|
-
saveScreenshot: () => Promise<BlueprintScreenshotResult>;
|
|
16397
|
-
/** Show the player the folder those pictures are in. */
|
|
16398
|
-
openScreenshotsFolder: () => Promise<BlueprintOpenScreenshotsResult>;
|
|
16399
|
-
/**
|
|
16400
|
-
* Whether this game's window is the one the player is working in right now.
|
|
16401
|
-
*
|
|
16402
|
-
* True wherever the shell cannot tell, which is the honest reading of "there is no window
|
|
16403
|
-
* to be behind": a story preview inside Studio is always the thing being looked at.
|
|
16404
|
-
*/
|
|
16405
|
-
isWindowFocused: () => Promise<boolean>;
|
|
16406
|
-
};
|
|
16407
|
-
/** Surfaces stacked over the page lane. See the `layers` family in `@shared/types/blueprint/hostApi`. */
|
|
16408
|
-
layers: {
|
|
16409
|
-
/** Put a page up as a layer and return the handle that names it. */
|
|
16410
|
-
show: (surfaceId: string, props?: unknown, options?: BlueprintLayerShowOptions) => Promise<string>;
|
|
16411
|
-
/** Take that layer down, settling once it has finished animating out. */
|
|
16412
|
-
hide: (handle: string) => Promise<void>;
|
|
16413
|
-
/** Take a whole group down - what is on screen and what is queued behind it. */
|
|
16414
|
-
hideGroup: (group: string) => Promise<void>;
|
|
16415
|
-
/** Wait for that layer to close and read what it closed with. Null for a handle already gone. */
|
|
16416
|
-
wait: (handle: string) => Promise<unknown>;
|
|
16417
|
-
/** Close the layer the calling graph runs in. A no-op with a warning anywhere else. */
|
|
16418
|
-
closeSelf: (result?: unknown) => Promise<void>;
|
|
16419
|
-
isMounted: (handle: string) => boolean;
|
|
16420
|
-
};
|
|
16421
|
-
widget: {
|
|
16422
|
-
setVisible: (elementId: string, visible: boolean) => Promise<void>;
|
|
16423
|
-
setEnabled: (elementId: string, enabled: boolean) => Promise<void>;
|
|
16424
|
-
/** `null` clears runtime override and restores authored default variant resolution. */
|
|
16425
|
-
setVariant: (elementId: string, variantId: string | null, options?: {
|
|
16426
|
-
waitForTransition?: boolean;
|
|
16427
|
-
}) => Promise<void>;
|
|
16428
|
-
getCommonProperties: (elementId: string) => BlueprintWidgetCommonProperties;
|
|
16429
|
-
getTextProperties: (elementId: string) => BlueprintTextProperties;
|
|
16430
|
-
setTextProperties: (elementId: string, patch: BlueprintTextPropertiesPatch) => Promise<void>;
|
|
16431
|
-
getButtonProperties: (elementId: string) => BlueprintButtonProperties;
|
|
16432
|
-
setButtonProperties: (elementId: string, patch: Partial<BlueprintButtonProperties>) => Promise<void>;
|
|
16433
|
-
getContainerProperties: (elementId: string) => BlueprintContainerProperties;
|
|
16434
|
-
setContainerProperties: (elementId: string, patch: Partial<BlueprintContainerProperties>) => Promise<void>;
|
|
16435
|
-
getImageProperties: (elementId: string) => BlueprintImageProperties;
|
|
16436
|
-
setImageProperties: (elementId: string, patch: Partial<BlueprintImageProperties>) => Promise<void>;
|
|
16437
|
-
getSliderProperties: (elementId: string) => BlueprintSliderProperties;
|
|
16438
|
-
setSliderProperties: (elementId: string, patch: BlueprintSliderPropertiesPatch) => Promise<void>;
|
|
16439
|
-
getSwitchProperties: (elementId: string) => BlueprintSwitchProperties;
|
|
16440
|
-
setSwitchProperties: (elementId: string, patch: BlueprintSwitchPropertiesPatch) => Promise<void>;
|
|
16441
|
-
getTextInputProperties: (elementId: string) => BlueprintTextInputProperties;
|
|
16442
|
-
setTextInputProperties: (elementId: string, patch: BlueprintTextInputPropertiesPatch) => Promise<void>;
|
|
16443
|
-
getListProperties: (elementId: string) => BlueprintListProperties;
|
|
16444
|
-
setListItems: (elementId: string, items: readonly unknown[]) => Promise<void>;
|
|
16445
|
-
setListSelectedIndex: (elementId: string, index: number) => Promise<void>;
|
|
16446
|
-
scrollListToIndex: (elementId: string, index: number) => Promise<void>;
|
|
16447
|
-
scrollListToTop: (elementId: string) => Promise<void>;
|
|
16448
|
-
scrollListToBottom: (elementId: string) => Promise<void>;
|
|
16449
|
-
getDisplayableProperties: (elementId: string) => BlueprintDisplayableProperties;
|
|
16450
|
-
/**
|
|
16451
|
-
* What the widget currently covers on screen, in the coordinates of the surface it is on,
|
|
16452
|
-
* or `null` when nothing is painted for it.
|
|
16453
|
-
*
|
|
16454
|
-
* Separate from {@link getDisplayableProperties} because the two answer different
|
|
16455
|
-
* questions. That one reads the document - where the author put the widget - and is the
|
|
16456
|
-
* right answer for layout arithmetic. This one measures the DOM, so it accounts for a
|
|
16457
|
-
* motion in flight, an appearance variant that shifted the widget, a text box sized to its
|
|
16458
|
-
* own words, and which row of a list an instance ended up on.
|
|
16459
|
-
*/
|
|
16460
|
-
getMeasuredRect: (elementId: string) => BlueprintRect | null;
|
|
16461
|
-
setDisplayableProperties: (elementId: string, patch: BlueprintDisplayablePropertiesPatch) => Promise<void>;
|
|
16462
|
-
animateDisplayable: (elementId: string, request: BlueprintDisplayableMotionRequest) => Promise<UIDisplayableMotionOverride>;
|
|
16463
|
-
stopDisplayableAnimation: (animationId: string) => Promise<void>;
|
|
16464
|
-
getFrameProperties: (elementId: string) => BlueprintFrameProperties;
|
|
16465
|
-
setFrameProperties: (elementId: string, patch: Partial<BlueprintFrameProperties>) => Promise<void>;
|
|
16466
|
-
};
|
|
16467
|
-
state: {
|
|
16468
|
-
get: (scope: string, key: string) => unknown;
|
|
16469
|
-
set: (scope: string, key: string, value: unknown) => void;
|
|
16470
|
-
};
|
|
16471
|
-
persistence: {
|
|
16472
|
-
get: (key: string) => Promise<unknown>;
|
|
16473
|
-
set: (key: string, value: unknown) => Promise<void>;
|
|
16474
|
-
};
|
|
16475
|
-
localization: {
|
|
16476
|
-
/** Localization setup of the running game, or null when the project has none. */
|
|
16477
|
-
getConfig: () => GameLocalizationConfigSnapshot | null;
|
|
16478
|
-
/** Effective current locale (stored player choice, else the source locale). */
|
|
16479
|
-
getLocale: () => Promise<string>;
|
|
16480
|
-
/** Persist the player's language choice; callers validate against getConfig(). */
|
|
16481
|
-
setLocale: (code: string) => Promise<void>;
|
|
16482
|
-
};
|
|
16483
|
-
/**
|
|
16484
|
-
* Voice-over: which dub the player hears, and replaying a take on demand.
|
|
16485
|
-
*
|
|
16486
|
-
* Separate from `localization` because dub language and subtitle language are separate player
|
|
16487
|
-
* choices - a game may be read in English and heard in Japanese.
|
|
16488
|
-
*/
|
|
16489
|
-
voice: {
|
|
16490
|
-
/** The dub languages this build ships, in project order. Empty when the game has no voice. */
|
|
16491
|
-
listLocales: () => VoiceLocaleEntry[];
|
|
16492
|
-
/** Effective dub language: the stored player choice when the build ships it, else the first. */
|
|
16493
|
-
getLocale: () => Promise<string>;
|
|
16494
|
-
/** Persist the player's dub choice. Takes effect from the next spoken line - no restart. */
|
|
16495
|
-
setLocale: (code: string) => Promise<void>;
|
|
16496
|
-
/**
|
|
16497
|
-
* Play one line's take in the current dub language, on that speaker's bus.
|
|
16498
|
-
*
|
|
16499
|
-
* The id is a voice unit id - the same id a backlog entry reports as `voiceId` - which is why
|
|
16500
|
-
* a replay button is built from this rather than from the entry's resolved URL. Resolves to
|
|
16501
|
-
* false when the line has no take in the current language.
|
|
16502
|
-
*/
|
|
16503
|
-
play: (unitId: string) => Promise<boolean>;
|
|
16504
|
-
/**
|
|
16505
|
-
* Play one choice option's take, at most one instance of that option at a time.
|
|
16506
|
-
*
|
|
16507
|
-
* Same clip and same bus as {@link play}; what differs is the bookkeeping a menu needs. A
|
|
16508
|
-
* hover fires as often as the pointer crosses a row, so a line already speaking is left
|
|
16509
|
-
* alone rather than restarted, and it answers false. `interruptOthers` stops the takes of
|
|
16510
|
-
* the *other* options - the author's call, because a menu that reads each option over the
|
|
16511
|
-
* last is as deliberate a design as one that speaks a single line at a time.
|
|
16512
|
-
*/
|
|
16513
|
-
playChoice: (unitId: string, options?: {
|
|
16514
|
-
interruptOthers?: boolean;
|
|
16515
|
-
}) => Promise<boolean>;
|
|
16516
|
-
};
|
|
16517
|
-
frame: {
|
|
16518
|
-
getParam: (key: string) => unknown;
|
|
16519
|
-
emit: (eventName: string, data: unknown) => Promise<void>;
|
|
16520
|
-
};
|
|
16521
|
-
game: {
|
|
16522
|
-
/**
|
|
16523
|
-
* Begin a story. `options.inheritSavedGame` carries a save's saved-scope values and visited
|
|
16524
|
-
* scenes into the new game - see the `Inherit From` pin - and carries nothing else.
|
|
16525
|
-
*/
|
|
16526
|
-
startStory: (request: DevModeStartStoryRequest, options?: {
|
|
16527
|
-
inheritSavedGame?: unknown;
|
|
16528
|
-
}) => Promise<void>;
|
|
16529
|
-
/** The running playthrough as a serialized game, or null when none is running. */
|
|
16530
|
-
captureRun: () => unknown | null;
|
|
16531
|
-
/** The serialized game stored in a slot, or null when there is no such slot. */
|
|
16532
|
-
readSaveGame: (id: string) => Promise<unknown | null>;
|
|
16533
|
-
isInGame: () => boolean;
|
|
16534
|
-
isGameOverlay: () => boolean;
|
|
16535
|
-
quit: (surfaceId: string) => Promise<void>;
|
|
16536
|
-
writeSave: (id: string, metadata?: unknown, screenshot?: boolean) => Promise<void>;
|
|
16537
|
-
/** False when the save was not applied - the player and the author have both been told. */
|
|
16538
|
-
loadSave: (id: string) => Promise<boolean>;
|
|
16539
|
-
deleteSave: (id: string) => Promise<void>;
|
|
16540
|
-
listSaveIds: () => Promise<string[]>;
|
|
16541
|
-
getSaveMetadata: (id: string) => Promise<unknown>;
|
|
16542
|
-
/** When a slot was written, or null when there is no such slot. */
|
|
16543
|
-
getSaveTimes: (id: string) => Promise<SaveRecordTimes | null>;
|
|
16544
|
-
/** Where a slot stopped, or null when there is no such slot. */
|
|
16545
|
-
getSaveLine: (id: string) => Promise<SaveRecordLine | null>;
|
|
16546
|
-
/** Which story a slot was written in, or null when there is no such slot. */
|
|
16547
|
-
getSaveStory: (id: string) => Promise<SaveRecordStory | null>;
|
|
16548
|
-
/** How long a slot was played, or null when there is no such slot. */
|
|
16549
|
-
getSavePlaytime: (id: string) => Promise<SaveRecordPlaytime | null>;
|
|
16550
|
-
/** The running playthrough's playtime, in seconds. */
|
|
16551
|
-
getPlaytime: () => number;
|
|
16552
|
-
/** Seconds ever spent in this project, across every playthrough. */
|
|
16553
|
-
getTotalPlaytime: () => number;
|
|
16554
|
-
getSavePreview: (id: string) => Promise<BlueprintImageAsset | null>;
|
|
16555
|
-
/** Write an autosave into the reserved ring now, regardless of the timer. */
|
|
16556
|
-
writeAutoSave: () => Promise<void>;
|
|
16557
|
-
/** The reserved autosave ring, newest first. Never overlaps `listSaveIds`. */
|
|
16558
|
-
listAutoSaves: () => Promise<AutoSaveEntry[]>;
|
|
16559
|
-
/**
|
|
16560
|
-
* The backlog behind the play head, oldest first.
|
|
16561
|
-
*
|
|
16562
|
-
* From engine 0.26.0 this stops at the head: after the player steps back, the lines they
|
|
16563
|
-
* stepped past are no longer in here, they are in {@link getFuture}. Before anyone steps
|
|
16564
|
-
* back - which is every ordinary playthrough - the two are the whole backlog and nothing.
|
|
16565
|
-
*/
|
|
16566
|
-
getHistory: () => Promise<BlueprintGameHistoryEntry[]>;
|
|
16567
|
-
/** The lines ahead of the play head, nearest first. Empty until the player steps back. */
|
|
16568
|
-
getFuture: () => Promise<BlueprintGameHistoryEntry[]>;
|
|
16569
|
-
/** Jump back to a history entry by id; omit the id to undo the last entry. */
|
|
16570
|
-
restoreHistory: (id?: string) => Promise<void>;
|
|
16571
|
-
/** Step the play head forward one line, back over a line the player has already read. */
|
|
16572
|
-
redoHistory: () => Promise<void>;
|
|
16573
|
-
canUndoHistory: () => boolean;
|
|
16574
|
-
canRedoHistory: () => boolean;
|
|
16575
|
-
getNametag: () => string | null;
|
|
16576
|
-
/**
|
|
16577
|
-
* The speaking character's dialog avatar, or null. Already keyed on the differential the
|
|
16578
|
-
* character is currently wearing - the engine resolves it off the live portrait element.
|
|
16579
|
-
*/
|
|
16580
|
-
getSpeakerAvatar: () => BlueprintImageAsset | null;
|
|
16581
|
-
/**
|
|
16582
|
-
* The speaking character's authored accent colour, already in pin shape. Opaque white when
|
|
16583
|
-
* nobody is speaking, the narrator is, or the character has no colour - the pin it feeds is
|
|
16584
|
-
* a non-nullable RGBAColor, so "no colour" and "the default colour" are the same answer.
|
|
16585
|
-
*/
|
|
16586
|
-
getSpeakerColor: () => BlueprintRGBAColor;
|
|
16587
|
-
/**
|
|
16588
|
-
* Has the line on screen finished revealing, with the dialog now waiting for the player.
|
|
16589
|
-
*
|
|
16590
|
-
* False while it is still typing, and false again the moment the next line mounts, so an
|
|
16591
|
-
* indicator bound to it needs no timer of its own. False with no dialog on screen at all.
|
|
16592
|
-
*/
|
|
16593
|
-
isDialogWaiting: () => boolean;
|
|
16594
|
-
/**
|
|
16595
|
-
* The current line's text - the whole line, not the part revealed so far. Empty string when
|
|
16596
|
-
* no line is on screen.
|
|
16597
|
-
*/
|
|
16598
|
-
getDialogText: () => string;
|
|
16599
|
-
/**
|
|
16600
|
-
* Does the current line have no speaker. Distinct from a null nametag, which a character
|
|
16601
|
-
* with a blank name also reports. False when no line is on screen.
|
|
16602
|
-
*/
|
|
16603
|
-
isNarrator: () => boolean;
|
|
16604
|
-
/**
|
|
16605
|
-
* Any character by id, from the table mirrored into global state - the addressable read the
|
|
16606
|
-
* speaker-scoped getters above cannot do. Null when the id is empty, or names a character
|
|
16607
|
-
* that is not (or is no longer) in the project.
|
|
16608
|
-
*/
|
|
16609
|
-
getCharacter: (characterId: string) => BlueprintCharacterInfo | null;
|
|
16610
|
-
getNotifications: () => BlueprintGameNotification[];
|
|
16611
|
-
getChoiceCount: () => number;
|
|
16612
|
-
isNvlMode: () => boolean;
|
|
16613
|
-
/** True while a dialog line is on screen and its message is marked read. */
|
|
16614
|
-
isCurrentTextRead: () => boolean;
|
|
16615
|
-
isTextRead: (textId: string) => boolean;
|
|
16616
|
-
/** Wipe the persisted text-read record (all stories). */
|
|
16617
|
-
clearTextRead: () => Promise<void>;
|
|
16618
|
-
/**
|
|
16619
|
-
* Has the player ever ENTERED this scene, by Studio scene id.
|
|
16620
|
-
*
|
|
16621
|
-
* Not the same question as `isTextRead`: that record is written when a line is displayed,
|
|
16622
|
-
* this one when a scene actually starts. Saved-domain, so loading an older save rewinds it.
|
|
16623
|
-
*/
|
|
16624
|
-
isSceneVisited: (sceneId: string) => boolean;
|
|
16625
|
-
/**
|
|
16626
|
-
* One saved variable of the running playthrough, by the id a `savedVariableRef` names.
|
|
16627
|
-
*
|
|
16628
|
-
* `found` is false with no game running, and with an id this build's story does not
|
|
16629
|
-
* declare. The two are worth telling apart from a value: `null` and the declared default
|
|
16630
|
-
* are both real values a variable can hold, so neither can double as "there was nothing to
|
|
16631
|
-
* read". See the capability's own note for why this is read-only.
|
|
16632
|
-
*/
|
|
16633
|
-
getSavedVariable: (variableId: string) => {
|
|
16634
|
-
value: unknown;
|
|
16635
|
-
found: boolean;
|
|
16636
|
-
};
|
|
16637
|
-
/**
|
|
16638
|
-
* Write one saved variable of the running playthrough.
|
|
16639
|
-
*
|
|
16640
|
-
* Throws when there is no game, when the id names nothing this build declares, and when the
|
|
16641
|
-
* value cannot go into a save file. All three are authoring errors a button would otherwise
|
|
16642
|
-
* swallow; see the capability's own note for what a write from a screen does and does not do.
|
|
16643
|
-
*/
|
|
16644
|
-
setSavedVariable: (variableId: string, value: unknown) => void;
|
|
16645
|
-
/**
|
|
16646
|
-
* Has the player ever PICKED this choice option, by the option row's Studio block id. The
|
|
16647
|
-
* one thing the text-read record structurally cannot answer - a menu that merely appeared
|
|
16648
|
-
* marks every option of it read.
|
|
16649
|
-
*/
|
|
16650
|
-
isOptionPicked: (optionId: string) => boolean;
|
|
16651
|
-
/**
|
|
16652
|
-
* Wipe the visited record of the running game.
|
|
16653
|
-
*
|
|
16654
|
-
* Synchronous, unlike `clearTextRead`: the record lives in the live `Storable`, not in host
|
|
16655
|
-
* persistence, so there is nothing to await. It is also scoped to the running session - with
|
|
16656
|
-
* no game up there is no record, and the call is a no-op instead of an error.
|
|
16657
|
-
*/
|
|
16658
|
-
clearVisited: () => void;
|
|
16659
|
-
/**
|
|
16660
|
-
* Has the player ever reached this ending, by the `ending` row's Studio block id.
|
|
16661
|
-
*
|
|
16662
|
-
* Project persistence rather than the save file, unlike the visited record above: an endings
|
|
16663
|
-
* screen reports what this player has ever seen, so loading an older save must not re-lock
|
|
16664
|
-
* anything. Needs no running story - a title screen asks it before the first game exists.
|
|
16665
|
-
*/
|
|
16666
|
-
isEndingReached: (endingId: string) => boolean;
|
|
16667
|
-
/**
|
|
16668
|
-
* Is this DLC installed beside the running build, by the id the author gave it.
|
|
16669
|
-
*
|
|
16670
|
-
* The whole of what a game may ask about its DLC, and deliberately not "does the player own
|
|
16671
|
-
* it". Ownership is a storefront's fact and a plugin's to answer; what decides whether the
|
|
16672
|
-
* content is here is whether its file is, which is the question this asks. A build with no
|
|
16673
|
-
* DLC beside it answers false to everything, which is what a title screen wants before the
|
|
16674
|
-
* player has bought anything.
|
|
16675
|
-
*/
|
|
16676
|
-
isDlcInstalled: (dlcId: string) => boolean;
|
|
16677
|
-
/**
|
|
16678
|
-
* Every ending one story declares, in document order, each row already carrying whether it
|
|
16679
|
-
* was reached. Empty for an unknown or unnamed story rather than an error.
|
|
16680
|
-
*
|
|
16681
|
-
* The list comes from the story document this build ships, so it can never offer an ending
|
|
16682
|
-
* the compiler does not emit, and it is available with no game running for the same reason
|
|
16683
|
-
* the reader above is.
|
|
16684
|
-
*/
|
|
16685
|
-
listEndings: (storyId: string) => BlueprintStoryEnding[];
|
|
16686
|
-
/**
|
|
16687
|
-
* Forget one ending. Awaited, unlike `clearVisited`: this writes host persistence rather
|
|
16688
|
-
* than a live `Storable`, and a caller that navigates away on the next beat has to know the
|
|
16689
|
-
* write landed.
|
|
16690
|
-
*/
|
|
16691
|
-
clearEndingState: (endingId: string) => Promise<void>;
|
|
16692
|
-
/** Wipe the whole endings record. The `Clear Text Read` of this family. */
|
|
16693
|
-
clearEndings: () => Promise<void>;
|
|
16694
|
-
choose: (index: number) => Promise<void>;
|
|
16695
|
-
next: () => Promise<void>;
|
|
16696
|
-
skip: () => Promise<void>;
|
|
16697
|
-
showDialog: () => Promise<void>;
|
|
16698
|
-
hideDialog: () => Promise<void>;
|
|
16699
|
-
toggleDialogDisplay: () => Promise<void>;
|
|
16700
|
-
setSentenceSpeed: (cps: number) => Promise<void>;
|
|
16701
|
-
getPreference: (key: BlueprintGamePreferenceKey) => BlueprintGamePreferenceValue;
|
|
16702
|
-
setPreference: (key: BlueprintGamePreferenceKey, value: BlueprintGamePreferenceValue) => Promise<void>;
|
|
16703
|
-
};
|
|
16704
|
-
sound: {
|
|
16705
|
-
play: (input: BlueprintSoundPlayInput) => Promise<BlueprintSoundHandle | null>;
|
|
16706
|
-
stop: (handle: BlueprintSoundHandle | null, fadeMs?: number) => Promise<void>;
|
|
16707
|
-
pause: (handle: BlueprintSoundHandle) => Promise<void>;
|
|
16708
|
-
resume: (handle: BlueprintSoundHandle) => Promise<void>;
|
|
16709
|
-
/** Ramp rather than jump when `fadeMs` is set - this is also the fade-out/duck node. */
|
|
16710
|
-
setVolume: (handle: BlueprintSoundHandle, volume: number, fadeMs?: number) => Promise<void>;
|
|
16711
|
-
/** Milliseconds from the start of the file, not from the clip's in point. */
|
|
16712
|
-
seek: (handle: BlueprintSoundHandle, timeMs: number) => Promise<void>;
|
|
16713
|
-
isPlaying: (handle: BlueprintSoundHandle) => boolean;
|
|
16714
|
-
/**
|
|
16715
|
-
* The volume a **host-owned** media element (the `nl.video` widget's `<video>`) must be set
|
|
16716
|
-
* to so it obeys the same mixer everything else does.
|
|
16717
|
-
*
|
|
16718
|
-
* A DOM element the host created sits on none of the engine's gain nodes, so the whole
|
|
16719
|
-
* product has to be computed and written to `element.volume`: the authored volume, times
|
|
16720
|
-
* every bus in the track's chain, times the player's slider for whichever seeded bus that
|
|
16721
|
-
* chain runs through, times master. Without this a muted game keeps playing video at full
|
|
16722
|
-
* volume. Pair it with {@link subscribeMixerChanges} - a value read once goes stale the
|
|
16723
|
-
* moment the player drags a slider, bus faders included.
|
|
16724
|
-
*/
|
|
16725
|
-
resolveElementVolume: (input: {
|
|
16726
|
-
audioTrackId?: string | null;
|
|
16727
|
-
volume?: number | null;
|
|
16728
|
-
}) => number;
|
|
16729
|
-
/** Fires when any preference feeding `resolveElementVolume` changes. Returns a disposer. */
|
|
16730
|
-
subscribeMixerChanges: (listener: () => void) => () => void;
|
|
16731
|
-
/**
|
|
16732
|
-
* An audio **track**'s own volume, 0..1 - one strip of the player's mixer.
|
|
16733
|
-
*
|
|
16734
|
-
* The player-facing counterpart of {@link setVolume}, which addresses one playing clip by
|
|
16735
|
-
* handle. A track is a bus every clip beneath it is routed through, so setting one applies
|
|
16736
|
-
* live to everything already playing and survives the clip that provoked it. This is what
|
|
16737
|
-
* makes "turn Alice down" expressible at all: the four fixed volume preferences can only
|
|
16738
|
-
* reach the three buses the engine seeds.
|
|
16739
|
-
*
|
|
16740
|
-
* An unknown or deleted track id reads as unity and writes nowhere, so a settings page
|
|
16741
|
-
* built against a track the author later removed degrades to an inert slider.
|
|
16742
|
-
*/
|
|
16743
|
-
getTrackVolume: (trackId: string) => number;
|
|
16744
|
-
setTrackVolume: (trackId: string, volume: number) => Promise<void>;
|
|
16745
|
-
};
|
|
16746
|
-
/**
|
|
16747
|
-
* HTTP, for the Fetch node.
|
|
16748
|
-
*
|
|
16749
|
-
* The host does not issue the request itself: it hands it to whatever the shell supplied, which
|
|
16750
|
-
* on desktop and in Dev Mode is the main process (`onNetworkFetch`). Nothing here calls
|
|
16751
|
-
* `fetch()` - see `@shared/utils/blueprintNetworkFetch` for why the renderer must not.
|
|
16752
|
-
*/
|
|
16753
|
-
network: {
|
|
16754
|
-
fetch: (request: BlueprintNetworkFetchRequest) => Promise<BlueprintNetworkFetchResult>;
|
|
16755
|
-
};
|
|
16756
|
-
/**
|
|
16757
|
-
* The read side of input routing, for `Is Action Held` and `Get Input Device`.
|
|
16758
|
-
*
|
|
16759
|
-
* The only part of the input model a graph can ask about rather than be told about. Everything
|
|
16760
|
-
* else in it is a dispatch - an action fires, a head runs - and none of that can answer "while
|
|
16761
|
-
* the gesture is down" or "with which hand", because a fired event leaves nothing behind that
|
|
16762
|
-
* says whether the hand is still there or what it was.
|
|
16763
|
-
*
|
|
16764
|
-
* Structural rather than a declared family in `@shared/types/blueprint/hostApi`, matching how
|
|
16765
|
-
* both nodes reach for it (see `BlueprintInputActionHostApi`): the contract there names
|
|
16766
|
-
* capabilities a host may or may not implement, and these are answered by the window every host
|
|
16767
|
-
* already has.
|
|
16768
|
-
*/
|
|
16769
|
-
input: {
|
|
16770
|
-
isActionHeld: (actionId: string) => boolean;
|
|
16771
|
-
/**
|
|
16772
|
-
* Which device the player is using at this moment.
|
|
16773
|
-
*
|
|
16774
|
-
* One of the four values the `On Action` head's `source` pin carries, typed as a plain
|
|
16775
|
-
* string so a graph compares both against the same literals.
|
|
16776
|
-
*/
|
|
16777
|
-
getDevice: () => string;
|
|
16778
|
-
};
|
|
16779
|
-
/**
|
|
16780
|
-
* Moving the player's real cursor, for the Move Mouse family.
|
|
16781
|
-
*
|
|
16782
|
-
* The author names a point in a surface's own coordinates, which is the only frame they have
|
|
16783
|
-
* reason to think in. Turning that into a point in the window happens here, off the same
|
|
16784
|
-
* surface shell every mouse event's payload is divided by, so "the centre of this button"
|
|
16785
|
-
* measured by `widget.getMeasuredRect` and the point the cursor lands on are the same place.
|
|
16786
|
-
*
|
|
16787
|
-
* `surfaceId` is the surface the point belongs to; `null` means the active one. A point on a
|
|
16788
|
-
* surface that is not currently laid out has nowhere to be, and reports `failed` rather than
|
|
16789
|
-
* being guessed at against a different surface's scale.
|
|
16790
|
-
*/
|
|
16791
|
-
pointer: {
|
|
16792
|
-
moveTo: (surfaceId: string | null, point: BlueprintVector2D, options?: BlueprintPointerMoveOptions) => Promise<BlueprintPointerMoveResult>;
|
|
16793
|
-
/**
|
|
16794
|
-
* The same act aimed at a widget's centre, measured rather than computed from the document.
|
|
16795
|
-
*
|
|
16796
|
-
* A method of its own rather than something a caller assembles out of `getMeasuredRect` and
|
|
16797
|
-
* `moveTo`, because the two halves have to agree about which surface the widget turned out
|
|
16798
|
-
* to be painted on. A component instance renders its contents wherever it was placed, so
|
|
16799
|
-
* the answer is not always the surface the element was authored under, and a caller
|
|
16800
|
-
* stitching the halves together would have to know that to get it right.
|
|
16801
|
-
*/
|
|
16802
|
-
moveToElementCenter: (elementId: string, options?: BlueprintPointerMoveOptions) => Promise<BlueprintPointerMoveResult>;
|
|
16803
|
-
};
|
|
16804
|
-
/**
|
|
16805
|
-
* Carrying a playthrough between two editions of one title, for the Export/Import Progress
|
|
16806
|
-
* nodes.
|
|
16807
|
-
*
|
|
16808
|
-
* The host does not decide where the document is: it hands the act to whatever the shell
|
|
16809
|
-
* supplied, and the shell's own process resolves the file from the build's progress key. What
|
|
16810
|
-
* this side states is what the playthrough holds, never where it goes.
|
|
16811
|
-
*
|
|
16812
|
-
* `import` answers with a scene id rather than going anywhere with it. The node deliberately
|
|
16813
|
-
* does not jump - `Start Game` is what starts a story, and an author's graph usually has
|
|
16814
|
-
* something to do first.
|
|
16815
|
-
*/
|
|
16816
|
-
progress: {
|
|
16817
|
-
export: () => Promise<{
|
|
16818
|
-
outcome: "written" | "failed";
|
|
16819
|
-
error: string;
|
|
16820
|
-
}>;
|
|
16821
|
-
import: () => Promise<GameProgressImportOutcome>;
|
|
16822
|
-
};
|
|
16823
|
-
/**
|
|
16824
|
-
* What the shell can promise about the data it writes, for the `Check Storage Durability` node.
|
|
16825
|
-
*
|
|
16826
|
-
* A fact about where the game is running, not about the playthrough: a packaged desktop game
|
|
16827
|
-
* keeps files nothing reclaims, a web export holds whatever grant the browser gave it. Stated,
|
|
16828
|
-
* never acted on - what a player is told about it belongs to the title.
|
|
16829
|
-
*/
|
|
16830
|
-
storage: {
|
|
16831
|
-
durability: () => Promise<GameStorageDurability>;
|
|
16832
|
-
};
|
|
16833
|
-
devtools: {
|
|
16834
|
-
log: (level: string, message: string) => void;
|
|
16835
|
-
};
|
|
16836
|
-
};
|
|
16837
|
-
type BlueprintSoundPlayInput = {
|
|
16838
|
-
assetId: string;
|
|
16839
|
-
/**
|
|
16840
|
-
* Project audio track (`ProjectAudioTrack.id`), which **is** the engine bus this clip is routed
|
|
16841
|
-
* into, and whose own gain is applied live by the gain graph rather than folded in here. It also
|
|
16842
|
-
* supplies the loop default below. Absent resolves to the seeded SFX bus, which is what an
|
|
16843
|
-
* unqualified "play this clip" has always meant.
|
|
16844
|
-
*/
|
|
16845
|
-
audioTrackId?: string | null;
|
|
16846
|
-
/** Author override; absent means the track's own default. */
|
|
16847
|
-
loop?: boolean | null;
|
|
16848
|
-
/** Author override, 0..1 as authored; absent means unity. Never pre-multiplied by a bus gain. */
|
|
16849
|
-
volume?: number | null;
|
|
16850
|
-
/** Fade-in in milliseconds; absent means a hard start (a fade belongs to the moment). */
|
|
16851
|
-
fadeInMs?: number | null;
|
|
16852
|
-
};
|
|
16853
|
-
type GameLocalizationConfigSnapshot = Pick<GameLocalizationBundle, "sourceLocale" | "locales"> & Partial<Pick<GameLocalizationBundle, "tables" | "keys" | "scenes">>;
|
|
16854
|
-
type BlueprintGameNotification = {
|
|
16855
|
-
id: string;
|
|
16856
|
-
message: string;
|
|
16857
|
-
};
|
|
16858
|
-
type BlueprintStoryEnding = {
|
|
16859
|
-
endingId: string;
|
|
16860
|
-
name: string;
|
|
16861
|
-
sceneId: string;
|
|
16862
|
-
/** The scene the ending row sits in, so a row can be grouped or captioned without a lookup. */
|
|
16863
|
-
sceneName: string;
|
|
16864
|
-
isReached: boolean;
|
|
16865
|
-
};
|
|
16866
|
-
type BlueprintGameHistoryEntry = {
|
|
16867
|
-
/** History token; pass to Restore From History to jump the game back to this point. */
|
|
16868
|
-
id: string;
|
|
16869
|
-
/** "say" for spoken lines, "menu" for a resolved choice. */
|
|
16870
|
-
type: "say" | "menu";
|
|
16871
|
-
/** Sentence text (say) or the menu prompt (menu); empty string when the source had none. */
|
|
16872
|
-
text: string;
|
|
16873
|
-
/** Speaker nametag for a say entry; null for menu entries or narration. */
|
|
16874
|
-
character: string | null;
|
|
16875
|
-
/** Resolved voice clip URL for a say entry; null when absent. Not addressable - see `voiceId`. */
|
|
16876
|
-
voice: string | null;
|
|
16877
|
-
/**
|
|
16878
|
-
* The voice unit id this line's take is filed under; null when the line was not voiced through
|
|
16879
|
-
* the voice module. This is the replayable handle: feed it to the Play Voice node. `voice` is a
|
|
16880
|
-
* URL the player already heard and nothing in the runtime accepts a URL.
|
|
16881
|
-
*/
|
|
16882
|
-
voiceId: string | null;
|
|
16883
|
-
/** Chosen option text for a menu entry; null for say entries or an unresolved menu. */
|
|
16884
|
-
selected: string | null;
|
|
16885
|
-
/** True while the entry is the line currently being shown (not yet committed). */
|
|
16886
|
-
isPending: boolean;
|
|
16887
|
-
};
|
|
16888
|
-
type BehaviorNodeExecuteResult = {
|
|
16889
|
-
nextPort?: string;
|
|
16890
|
-
nextPorts?: string[];
|
|
16891
|
-
outputValues?: Record<string, unknown>;
|
|
16892
|
-
};
|
|
16893
|
-
type BehaviorGraphEventControl = {
|
|
16894
|
-
stopPropagation(): void;
|
|
16895
|
-
isPropagationStopped(): boolean;
|
|
16896
|
-
};
|
|
16897
|
-
type StoryBlockSelection = {
|
|
16898
|
-
editor: "story";
|
|
16899
|
-
tabId: string;
|
|
16900
|
-
storyId: StoryId;
|
|
16901
|
-
sceneId: StorySceneId;
|
|
16902
|
-
/** The focused row, or null when the scene itself is the subject. */
|
|
16903
|
-
blockId: StoryBlockId | null;
|
|
16904
|
-
};
|
|
16905
|
-
type StoryMotionKeyframeSelection = {
|
|
16906
|
-
editor: "story-motion";
|
|
16907
|
-
tabId: string;
|
|
16908
|
-
animationId: string;
|
|
16909
|
-
trackId: string;
|
|
16910
|
-
keyframeId: string;
|
|
16911
|
-
};
|
|
16912
|
-
type ComparisonHalf = "base" | "head";
|
|
16913
|
-
interface ComparisonElementSelection {
|
|
16914
|
-
/** Repository-relative path of the document being compared. Identity, not a read address. */
|
|
16915
|
-
readonly documentPath: string;
|
|
16916
|
-
readonly half: ComparisonHalf;
|
|
16917
|
-
/** What that half calls its version, already resolved to text by the tab that knows. */
|
|
16918
|
-
readonly versionLabel: string;
|
|
16919
|
-
/** What the OTHER half calls its version. The strip names it when the element is not in it. */
|
|
16920
|
-
readonly counterpartLabel: string;
|
|
16921
|
-
readonly surfaceId: string;
|
|
16922
|
-
readonly elementId: string;
|
|
16923
|
-
/** The element, out of that half's parsed document. */
|
|
16924
|
-
readonly element: UIElement;
|
|
16925
|
-
/** That half's whole document, so a field can resolve a parent, a component or a binding. */
|
|
16926
|
-
readonly document: UIDocument;
|
|
16927
|
-
/** The same element in the other half, or null when that half does not hold it. */
|
|
16928
|
-
readonly counterpart: UIElement | null;
|
|
16929
|
-
/** The other half's document, for the fields that read one. Null when there is no other half. */
|
|
16930
|
-
readonly counterpartDocument: UIDocument | null;
|
|
16931
|
-
}
|
|
16932
|
-
/**
|
|
16933
|
-
* What a plugin may add to Studio's built-in text editor.
|
|
16934
|
-
*
|
|
16935
|
-
* Studio ships the editor and nothing on top of it: no Markdown preview, no lint, no formatter.
|
|
16936
|
-
* Those are plugin work, and this module is the whole of what a plugin needs to do them - a
|
|
16937
|
-
* grammar, a preview pane, a command. The host registry is
|
|
16938
|
-
* `TextEditorContributionService`; the plugin-facing names are re-exported from
|
|
16939
|
-
* `@/plugin` and published in the `narraleaf-studio` types package.
|
|
16940
|
-
*
|
|
16941
|
-
* Two rules the rest of the design follows from:
|
|
16942
|
-
*
|
|
16943
|
-
* - **Imperative, not declarative.** There is no `contributes.textEditor` manifest key, for the
|
|
16944
|
-
* same reason `ui.panels` has none: nothing outside the editor session needs to know these
|
|
16945
|
-
* exist, so a static declaration would be bookkeeping with no reader.
|
|
16946
|
-
* - **Nothing is rendered for an empty registry.** A preview toggle with no preview behind it is
|
|
16947
|
-
* a dead control, and the editor's status bar is values-only by design. The consumer shows the
|
|
16948
|
-
* toggles for the previews that match *this* document's extension and nothing otherwise.
|
|
16949
|
-
*/
|
|
16950
|
-
/** The character encoding a document is currently being read and written in. */
|
|
16951
|
-
export type PluginTextEditorEncodingId = TextEncodingId;
|
|
16952
|
-
/**
|
|
16953
|
-
* A Monarch grammar - monaco's `languages.IMonarchLanguage`.
|
|
16954
|
-
*
|
|
16955
|
-
* Typed structurally rather than by importing monaco's declarations: the published
|
|
16956
|
-
* `narraleaf-studio` types package would otherwise have to carry monaco's entire `.d.ts` surface,
|
|
16957
|
-
* and a plugin would need monaco installed to write a twenty-line grammar. The host casts on the
|
|
16958
|
-
* way into `monaco.languages.setMonarchTokensProvider`.
|
|
16959
|
-
*/
|
|
16960
|
-
export type PluginTextEditorMonarchGrammar = {
|
|
16961
|
-
tokenizer: Record<string, unknown>;
|
|
16962
|
-
[key: string]: unknown;
|
|
16963
|
-
};
|
|
16964
|
-
/** A monaco `languages.LanguageConfiguration` (comments, brackets, auto-closing pairs, folding). */
|
|
16965
|
-
export type PluginTextEditorLanguageConfiguration = Record<string, unknown>;
|
|
16966
|
-
/**
|
|
16967
|
-
* A language the built-in editor should colour.
|
|
16968
|
-
*
|
|
16969
|
-
* Registered into monaco **lazily** - the first time a document with one of these extensions is
|
|
16970
|
-
* opened, not when the plugin's `setup` runs. Monaco is a large module that Studio loads on the
|
|
16971
|
-
* first text tab and never before; a language registration at setup time would drag it into
|
|
16972
|
-
* startup for every workspace, whether or not a text file is ever opened.
|
|
16973
|
-
*/
|
|
16974
|
-
export type PluginTextEditorLanguageDef = {
|
|
16975
|
-
/** Monaco language id. Must be prefixed with the plugin id. */
|
|
16976
|
-
id: string;
|
|
16977
|
-
/** File extensions, with or without the leading dot; matched case-insensitively. */
|
|
16978
|
-
extensions: string[];
|
|
16979
|
-
aliases?: string[];
|
|
16980
|
-
monarch?: PluginTextEditorMonarchGrammar;
|
|
16981
|
-
configuration?: PluginTextEditorLanguageConfiguration;
|
|
16982
|
-
};
|
|
15790
|
+
export type PluginTextEditorLanguageDef = {
|
|
15791
|
+
/** Monaco language id. Must be prefixed with the plugin id. */
|
|
15792
|
+
id: string;
|
|
15793
|
+
/** File extensions, with or without the leading dot; matched case-insensitively. */
|
|
15794
|
+
extensions: string[];
|
|
15795
|
+
aliases?: string[];
|
|
15796
|
+
monarch?: PluginTextEditorMonarchGrammar;
|
|
15797
|
+
configuration?: PluginTextEditorLanguageConfiguration;
|
|
15798
|
+
};
|
|
16983
15799
|
/**
|
|
16984
15800
|
* What a preview component is handed on every render.
|
|
16985
15801
|
*
|
|
@@ -17078,176 +15894,6 @@ type SelectionState = {
|
|
|
17078
15894
|
type: "storyBlock";
|
|
17079
15895
|
data: StoryBlockSelection;
|
|
17080
15896
|
};
|
|
17081
|
-
type ViewportTransform = {
|
|
17082
|
-
scale: number;
|
|
17083
|
-
offsetX: number;
|
|
17084
|
-
offsetY: number;
|
|
17085
|
-
};
|
|
17086
|
-
type CanvasFitMode = "contain" | "cover" | "width" | "actual";
|
|
17087
|
-
type SurfaceViewportFit = {
|
|
17088
|
-
mode: CanvasFitMode;
|
|
17089
|
-
/**
|
|
17090
|
-
* True when the mode came from the zoom menu. It survives a resize the same way, and only this
|
|
17091
|
-
* one escapes {@link SURFACE_FIT_MAX_SCALE}.
|
|
17092
|
-
*/
|
|
17093
|
-
chosen: boolean;
|
|
17094
|
-
};
|
|
17095
|
-
type UITool = {
|
|
17096
|
-
kind: "select";
|
|
17097
|
-
} | {
|
|
17098
|
-
kind: "pan";
|
|
17099
|
-
} | {
|
|
17100
|
-
kind: "insert";
|
|
17101
|
-
nodeType: string;
|
|
17102
|
-
componentId?: string;
|
|
17103
|
-
};
|
|
17104
|
-
type SnapGuideKind = "surface-edge" | "surface-center" | "element-edge" | "element-center";
|
|
17105
|
-
type ActiveSnapGuideSegment = {
|
|
17106
|
-
value: number;
|
|
17107
|
-
kind: SnapGuideKind;
|
|
17108
|
-
};
|
|
17109
|
-
type ActiveSnapGuides = {
|
|
17110
|
-
surfaceId: string;
|
|
17111
|
-
vertical: ActiveSnapGuideSegment[];
|
|
17112
|
-
horizontal: ActiveSnapGuideSegment[];
|
|
17113
|
-
};
|
|
17114
|
-
type SmartSnapDetailSettings = {
|
|
17115
|
-
/** Snap selection edges/centers to other elements' center lines. */
|
|
17116
|
-
snapElementLayout: boolean;
|
|
17117
|
-
/** Snap element edges to other elements' edges. */
|
|
17118
|
-
snapElementBorder: boolean;
|
|
17119
|
-
/** Snap to canvas (surface) edges and center lines. */
|
|
17120
|
-
snapCanvasLayout: boolean;
|
|
17121
|
-
};
|
|
17122
|
-
declare class UIEditorStateService extends Service<UIEditorStateService> implements IUIEditorStateService {
|
|
17123
|
-
private uiStore;
|
|
17124
|
-
private documentService;
|
|
17125
|
-
private settingsService;
|
|
17126
|
-
private readonly events;
|
|
17127
|
-
private selection;
|
|
17128
|
-
private tool;
|
|
17129
|
-
private viewport;
|
|
17130
|
-
/** Which interface {@link viewport} currently describes - it is one transform shared by every tab. */
|
|
17131
|
-
private viewportSurfaceId;
|
|
17132
|
-
/**
|
|
17133
|
-
* Set while {@link viewport} is a computed zoom - a fit mode rather than somewhere the author
|
|
17134
|
-
* zoomed or panned to by hand. `null` means the transform is theirs and nothing may revise it.
|
|
17135
|
-
*/
|
|
17136
|
-
private viewportFit;
|
|
17137
|
-
/** Hand-set transforms, so switching back to an interface returns to the view it was left at. */
|
|
17138
|
-
private readonly viewportBySurfaceId;
|
|
17139
|
-
/** Fit modes, so switching back to an interface resumes the mode it was left following. */
|
|
17140
|
-
private readonly viewportFitBySurfaceId;
|
|
17141
|
-
private interactionOverride;
|
|
17142
|
-
private selectionUnsubscribe?;
|
|
17143
|
-
private enteredState;
|
|
17144
|
-
/** Only stores `true` keys; missing id => collapsed. */
|
|
17145
|
-
private readonly appearanceBorderSidesExpandedByElementId;
|
|
17146
|
-
private appearanceInspectorUiCachePersistTimer;
|
|
17147
|
-
/** Presence means the outline branch is collapsed. */
|
|
17148
|
-
private readonly outlineCollapsedBranchIds;
|
|
17149
|
-
private outlinePanelCollapsed;
|
|
17150
|
-
private outlineCollapsePersistTimer;
|
|
17151
|
-
private smartSnapEnabled;
|
|
17152
|
-
private smartSnapDetail;
|
|
17153
|
-
private snapGuides;
|
|
17154
|
-
/** Pure view state: screen-ratio preview frame preset id, `null` = off. Never touches the UIDocument. */
|
|
17155
|
-
private previewAspectId;
|
|
17156
|
-
/** Pure view state: safe-area preview frame device preset id, `null` = off. Never touches the UIDocument. */
|
|
17157
|
-
private previewSafeAreaId;
|
|
17158
|
-
protected init(ctx: WorkspaceContext, depend: (services: Service[]) => Promise<void>): Promise<void>;
|
|
17159
|
-
dispose(_ctx: WorkspaceContext): void;
|
|
17160
|
-
getTool(): UITool;
|
|
17161
|
-
setTool(tool: UITool): void;
|
|
17162
|
-
getViewportTransform(): ViewportTransform;
|
|
17163
|
-
/**
|
|
17164
|
-
* A hand gesture: a wheel zoom, a pan, or a zoom the author typed. It ends whatever fit mode
|
|
17165
|
-
* was running, because from here on the author has said where they want to be looking and a
|
|
17166
|
-
* pane resize must not overrule that.
|
|
17167
|
-
*/
|
|
17168
|
-
updateViewport(transform: Partial<ViewportTransform>): ViewportTransform;
|
|
17169
|
-
/** Which interface the current transform describes; `null` before any editor tab claimed it. */
|
|
17170
|
-
getViewportSurfaceId(): string | null;
|
|
17171
|
-
/**
|
|
17172
|
-
* The fit mode the viewport is currently following, or `null` once the author has zoomed or
|
|
17173
|
-
* panned by hand. Only while it is set may the editor recompute the transform on its own, when
|
|
17174
|
-
* the pane resizes or the design size changes.
|
|
17175
|
-
*/
|
|
17176
|
-
getViewportFit(): SurfaceViewportFit | null;
|
|
17177
|
-
/**
|
|
17178
|
-
* Installs a computed zoom as the viewport for `surfaceId`.
|
|
17179
|
-
*
|
|
17180
|
-
* Separate from {@link updateViewport} because the two carry opposite intent: this one is a
|
|
17181
|
-
* mode being applied, and it stays live across resizes; that one is a place the author chose,
|
|
17182
|
-
* and nothing may move it.
|
|
17183
|
-
*/
|
|
17184
|
-
applyFittedViewport(surfaceId: string, transform: ViewportTransform, fit: SurfaceViewportFit): ViewportTransform;
|
|
17185
|
-
/**
|
|
17186
|
-
* Hands the shared viewport to `surfaceId` when opening or re-showing its tab.
|
|
17187
|
-
*
|
|
17188
|
-
* One transform serves every surface editor tab, so switching tabs would otherwise show the
|
|
17189
|
-
* next interface through the last one's zoom.
|
|
17190
|
-
*
|
|
17191
|
-
* Returns `null` when this interface was left at a hand-set transform - it has been restored
|
|
17192
|
-
* and the caller has nothing to do. Otherwise returns the mode the caller must recompute for
|
|
17193
|
-
* the space it has now, which for an interface being opened for the first time is the plain
|
|
17194
|
-
* fit nobody asked for.
|
|
17195
|
-
*/
|
|
17196
|
-
adoptSurfaceViewport(surfaceId: string): SurfaceViewportFit | null;
|
|
17197
|
-
getSelection(): SelectionState;
|
|
17198
|
-
setSelection(selection: SelectionState): void;
|
|
17199
|
-
setUIElementSelection(selection: UIElementSelection): void;
|
|
17200
|
-
getInteractionOverride(): InteractionOverride | null;
|
|
17201
|
-
setInteractionOverride(next: InteractionOverride | null): void;
|
|
17202
|
-
getDocument(): UIDocument;
|
|
17203
|
-
getSurface(surfaceId: string): UISurface | undefined;
|
|
17204
|
-
getEnteredState(): UIEditorEnteredState | null;
|
|
17205
|
-
setEnteredState(next: UIEditorEnteredState | null): void;
|
|
17206
|
-
getAppearanceBorderSidesExpanded(elementId: string): boolean;
|
|
17207
|
-
setAppearanceBorderSidesExpanded(elementId: string, expanded: boolean): void;
|
|
17208
|
-
isOutlineBranchCollapsed(elementId: string): boolean;
|
|
17209
|
-
setOutlineBranchCollapsed(elementId: string, collapsed: boolean): void;
|
|
17210
|
-
getOutlinePanelCollapsed(): boolean;
|
|
17211
|
-
setOutlinePanelCollapsed(collapsed: boolean): void;
|
|
17212
|
-
getSmartSnapEnabled(): boolean;
|
|
17213
|
-
setSmartSnapEnabled(enabled: boolean): void;
|
|
17214
|
-
getSmartSnapDetailSettings(): SmartSnapDetailSettings;
|
|
17215
|
-
patchSmartSnapDetailSettings(patch: Partial<SmartSnapDetailSettings>): void;
|
|
17216
|
-
getPreviewAspectId(): string | null;
|
|
17217
|
-
/**
|
|
17218
|
-
* Pure view state — persisted in global settings only. Deliberately does NOT go through
|
|
17219
|
-
* `UIDocumentService`, so toggling a preview frame never dirties the project, never emits
|
|
17220
|
-
* `documentChanged` and never enters the undo stack.
|
|
17221
|
-
*/
|
|
17222
|
-
setPreviewAspectId(aspectId: string | null): void;
|
|
17223
|
-
getPreviewSafeAreaId(): string | null;
|
|
17224
|
-
/** Pure view state — see `setPreviewAspectId`. */
|
|
17225
|
-
setPreviewSafeAreaId(safeAreaId: string | null): void;
|
|
17226
|
-
getSnapGuides(): ActiveSnapGuides | null;
|
|
17227
|
-
setSnapGuides(guides: ActiveSnapGuides | null): void;
|
|
17228
|
-
on<K extends keyof UIEditorStateEvents>(event: K, handler: (data: UIEditorStateEvents[K]) => void): () => void;
|
|
17229
|
-
private ensureUIStore;
|
|
17230
|
-
private normalizeViewport;
|
|
17231
|
-
private persistViewport;
|
|
17232
|
-
private scheduleAppearanceInspectorUiCachePersistence;
|
|
17233
|
-
private persistAppearanceInspectorUiCachesNow;
|
|
17234
|
-
private flushAppearanceInspectorUiCachePersistence;
|
|
17235
|
-
private scheduleOutlineCollapsePersistence;
|
|
17236
|
-
private persistOutlineCollapsedBranchesNow;
|
|
17237
|
-
private flushOutlineCollapsePersistence;
|
|
17238
|
-
private areSnapGuidesEqual;
|
|
17239
|
-
/**
|
|
17240
|
-
* Drops the entered state when the author moves to another interface.
|
|
17241
|
-
*
|
|
17242
|
-
* Selection is left alone on purpose. A canvas click on a widget's part promotes the selection to
|
|
17243
|
-
* the parent it drills from, so exiting on "the selection left the subtree" exits on the very
|
|
17244
|
-
* click an author makes to grab what they are editing - the state flickered away under them, and
|
|
17245
|
-
* whatever they did next landed somewhere they were not looking.
|
|
17246
|
-
*/
|
|
17247
|
-
private ensureEnteredStateValid;
|
|
17248
|
-
private ensureInteractionOverrideValid;
|
|
17249
|
-
private areOverridesEqual;
|
|
17250
|
-
}
|
|
17251
15897
|
type LiveUIComponentShell = Omit<UIComponentDefinition, "elements">;
|
|
17252
15898
|
type LiveUIParts = {
|
|
17253
15899
|
/** Records of the shared element map. */
|
|
@@ -18258,53 +16904,6 @@ interface PropertyEditorSchema<TData = any> {
|
|
|
18258
16904
|
/** Whether to show saving indicator */
|
|
18259
16905
|
showSavingIndicator?: boolean;
|
|
18260
16906
|
}
|
|
18261
|
-
type WidgetRendererProps = {
|
|
18262
|
-
element: UIElement;
|
|
18263
|
-
surface: UISurface;
|
|
18264
|
-
document: UIDocument;
|
|
18265
|
-
hostAdapter: UIHostAdapter;
|
|
18266
|
-
children?: React$1.ReactNode;
|
|
18267
|
-
/** Stable suffix for repeated structural renderers such as list item previews. */
|
|
18268
|
-
instanceKey?: string;
|
|
18269
|
-
/** Current list item scope when this element renders inside a list-like item template. */
|
|
18270
|
-
listItemScope?: UIListItemScope | null;
|
|
18271
|
-
/**
|
|
18272
|
-
* Structural widgets may render children lazily with an instance scope.
|
|
18273
|
-
* `nl.list` uses this to repeat one authored item template without cloning UIDocument elements.
|
|
18274
|
-
*/
|
|
18275
|
-
renderChildren?: (options?: {
|
|
18276
|
-
childrenIds?: string[];
|
|
18277
|
-
listItemScope?: UIListItemScope | null;
|
|
18278
|
-
instanceKey?: string;
|
|
18279
|
-
elementOverrides?: Record<string, UIElement>;
|
|
18280
|
-
}) => React$1.ReactNode[];
|
|
18281
|
-
/**
|
|
18282
|
-
* Render another Page surface inside the current element without using an iframe.
|
|
18283
|
-
* Runtime hosts may isolate state/lifecycle by frame instance.
|
|
18284
|
-
*/
|
|
18285
|
-
renderSurface?: (options: {
|
|
18286
|
-
targetSurfaceId: string | null;
|
|
18287
|
-
frameElement: UIElement;
|
|
18288
|
-
params?: Record<string, unknown>;
|
|
18289
|
-
instanceKey?: string;
|
|
18290
|
-
}) => React$1.ReactNode;
|
|
18291
|
-
/** Runtime state readers exposed to structural widgets that resolve their own data source. */
|
|
18292
|
-
runtimeData?: {
|
|
18293
|
-
surfaceState?: {
|
|
18294
|
-
get(key: string): unknown;
|
|
18295
|
-
};
|
|
18296
|
-
globalState?: {
|
|
18297
|
-
get(key: string): unknown;
|
|
18298
|
-
};
|
|
18299
|
-
/** Props the current page was opened with; fixed for the life of the page instance. */
|
|
18300
|
-
pageProps?: Readonly<Record<string, unknown>>;
|
|
18301
|
-
};
|
|
18302
|
-
/**
|
|
18303
|
-
* When true, canvas appearance resolves the variant from the inspector cache (editing-area preview).
|
|
18304
|
-
* Dev Mode and other hosts omit this so runtime/blueprint variant overrides stay authoritative.
|
|
18305
|
-
*/
|
|
18306
|
-
useAppearanceInspectorPreview?: boolean;
|
|
18307
|
-
};
|
|
18308
16907
|
type UIInspectorData = {
|
|
18309
16908
|
element: UIElement;
|
|
18310
16909
|
elements: UIElement[];
|
|
@@ -18313,10 +16912,6 @@ type UIInspectorData = {
|
|
|
18313
16912
|
/** Set when inspecting a canvas widget; required for Blueprint M2 binding UI. */
|
|
18314
16913
|
surfaceId?: string;
|
|
18315
16914
|
};
|
|
18316
|
-
type InspectorContext = {
|
|
18317
|
-
element: UIElement;
|
|
18318
|
-
documentService: UIDocumentService;
|
|
18319
|
-
};
|
|
18320
16915
|
type DockerBarItem = DockerBarButton | DockerBarSelect | DockerBarNumberInput | DockerBarSeparator;
|
|
18321
16916
|
type DockerBarButton = {
|
|
18322
16917
|
kind: "button";
|
|
@@ -18361,17 +16956,6 @@ type DockerBarSeparator = {
|
|
|
18361
16956
|
kind: "separator";
|
|
18362
16957
|
id: string;
|
|
18363
16958
|
};
|
|
18364
|
-
type DockerBarContext = {
|
|
18365
|
-
element: UIElement;
|
|
18366
|
-
documentService: UIDocumentService;
|
|
18367
|
-
stateService?: UIEditorStateService;
|
|
18368
|
-
surfaceId?: string;
|
|
18369
|
-
};
|
|
18370
|
-
type WidgetContextMenuContext = {
|
|
18371
|
-
element: UIElement;
|
|
18372
|
-
documentService: UIDocumentService;
|
|
18373
|
-
surfaceId: string;
|
|
18374
|
-
};
|
|
18375
16959
|
type FloatingToolbarButton = {
|
|
18376
16960
|
kind: "button";
|
|
18377
16961
|
id: string;
|
|
@@ -18382,18 +16966,6 @@ type FloatingToolbarButton = {
|
|
|
18382
16966
|
onClick: () => void;
|
|
18383
16967
|
};
|
|
18384
16968
|
type FloatingToolbarItem = FloatingToolbarButton;
|
|
18385
|
-
type FloatingToolbarContext = {
|
|
18386
|
-
element: UIElement;
|
|
18387
|
-
documentService: UIDocumentService;
|
|
18388
|
-
surfaceId: string;
|
|
18389
|
-
openSurfaceEditor?: (surfaceId: string) => void;
|
|
18390
|
-
};
|
|
18391
|
-
type LayoutSizeFieldContext = {
|
|
18392
|
-
element: UIElement;
|
|
18393
|
-
documentService: UIDocumentService;
|
|
18394
|
-
surfaceId?: string;
|
|
18395
|
-
primaryId: string;
|
|
18396
|
-
};
|
|
18397
16969
|
type DefaultChildElementContext = {
|
|
18398
16970
|
element: UIElement;
|
|
18399
16971
|
generateId: () => string;
|
|
@@ -18402,203 +16974,6 @@ type DefaultChildElementResult = {
|
|
|
18402
16974
|
elementPatch?: Partial<UIElement>;
|
|
18403
16975
|
children: UIElement[];
|
|
18404
16976
|
};
|
|
18405
|
-
interface UIWidgetModule {
|
|
18406
|
-
/** Unique type identifier (e.g. "nl.container") */
|
|
18407
|
-
readonly type: string;
|
|
18408
|
-
/**
|
|
18409
|
-
* Widget type this module specialises, set by `extendWidgetModule`.
|
|
18410
|
-
*
|
|
18411
|
-
* Mirrors the entry in `WIDGET_TYPE_PARENTS`, which is the shared table the capability lookups
|
|
18412
|
-
* (effect kinds, logic API, appearance backfill) read - `shared` cannot see a renderer module.
|
|
18413
|
-
*/
|
|
18414
|
-
readonly extends?: string;
|
|
18415
|
-
/** Shared logic capability schema for editor, runtime, and blueprint tooling. */
|
|
18416
|
-
readonly logicApi?: WidgetLogicApi;
|
|
18417
|
-
/** Human-readable display name */
|
|
18418
|
-
readonly displayName: string;
|
|
18419
|
-
/** Icon shown in the docker bar's element palette */
|
|
18420
|
-
readonly icon: LucideIcon;
|
|
18421
|
-
/**
|
|
18422
|
-
* Creates the default partial element when the user inserts this widget.
|
|
18423
|
-
* The returned object is merged with system defaults (id, parentId, etc.).
|
|
18424
|
-
*/
|
|
18425
|
-
createDefaultElement(): Partial<UIElement>;
|
|
18426
|
-
/**
|
|
18427
|
-
* Creates structural child elements that must be present immediately after inserting the widget.
|
|
18428
|
-
* The service applies the returned parent patch and child list in the same UIDocument mutation.
|
|
18429
|
-
*/
|
|
18430
|
-
createDefaultChildElements?(context: DefaultChildElementContext): DefaultChildElementResult;
|
|
18431
|
-
/**
|
|
18432
|
-
* The states this widget can be shown in, when they belong to the widget rather than to an
|
|
18433
|
-
* appearance model.
|
|
18434
|
-
*
|
|
18435
|
-
* A switch is on or off whatever its parts look like, and it carries no appearance of its own, so
|
|
18436
|
-
* there are no variants for the state bar to list. Declaring them here puts the bar on the widget
|
|
18437
|
-
* itself; entering one broadcasts that variant id to the subtree, which is where the parts that
|
|
18438
|
-
* do carry variants pick it up. `id: null` is the state the widget rests in.
|
|
18439
|
-
*/
|
|
18440
|
-
listEditorStates?(element: UIElement): {
|
|
18441
|
-
id: string | null;
|
|
18442
|
-
name: string;
|
|
18443
|
-
}[];
|
|
18444
|
-
/**
|
|
18445
|
-
* Renders the element on the editor canvas.
|
|
18446
|
-
*/
|
|
18447
|
-
render(props: WidgetRendererProps): React$1.ReactElement | null;
|
|
18448
|
-
/**
|
|
18449
|
-
* Returns property inspector fields for the properties panel.
|
|
18450
|
-
* These fields are appended after the common layout fields.
|
|
18451
|
-
* Return `undefined` to show only layout fields.
|
|
18452
|
-
*/
|
|
18453
|
-
createInspector?(context: InspectorContext): PropertyEditorSchema<UIInspectorData> | undefined;
|
|
18454
|
-
/**
|
|
18455
|
-
* Returns docker bar items shown when this element is selected.
|
|
18456
|
-
* Return `undefined` or empty array for no element-specific docker items.
|
|
18457
|
-
*/
|
|
18458
|
-
createDockerBarItems?(context: DockerBarContext): DockerBarItem[];
|
|
18459
|
-
/**
|
|
18460
|
-
* Returns docker bar items used when multiple elements of this type are selected.
|
|
18461
|
-
* The final multi-select docker bar shows only the items whose `id` exists for every selected module.
|
|
18462
|
-
*/
|
|
18463
|
-
createMultiSelectDockerBarItems?(context: DockerBarContext): DockerBarItem[];
|
|
18464
|
-
/**
|
|
18465
|
-
* Extra context menu items when this element is the sole selection (canvas or outline).
|
|
18466
|
-
*/
|
|
18467
|
-
createContextMenuItems?(context: WidgetContextMenuContext): ContextMenuItemDef[];
|
|
18468
|
-
/**
|
|
18469
|
-
* Returns icon actions rendered as one floating toolbar above the selected element's transform box.
|
|
18470
|
-
* Keep actions concise; all modules share the same group renderer.
|
|
18471
|
-
*/
|
|
18472
|
-
createFloatingToolbarItems?(context: FloatingToolbarContext): FloatingToolbarItem[];
|
|
18473
|
-
/**
|
|
18474
|
-
* Override the common Width / Height row in the layout inspector.
|
|
18475
|
-
* Return `undefined` to use the default row, or `null` to hide the row.
|
|
18476
|
-
*/
|
|
18477
|
-
createLayoutSizeField?(context: LayoutSizeFieldContext): FieldDefinition<UIInspectorData> | null | undefined;
|
|
18478
|
-
/**
|
|
18479
|
-
* Optional hook to register additional blueprint nodes (via `defineBlueprintNode`) when the module loads.
|
|
18480
|
-
* Keep side effects idempotent - the host may call this once per session.
|
|
18481
|
-
*/
|
|
18482
|
-
registerBlueprintNodes?(): void;
|
|
18483
|
-
}
|
|
18484
|
-
type UIEditorReadOnly = {
|
|
18485
|
-
/** Whether every write gesture on this surface is inert right now. */
|
|
18486
|
-
readonly active: boolean;
|
|
18487
|
-
/** Hover text for the controls this state disables. The workspace passes the freeze reason. */
|
|
18488
|
-
readonly reason?: string;
|
|
18489
|
-
};
|
|
18490
|
-
type UIHost$1 = "app" | "player";
|
|
18491
|
-
type UIHostAdapterElementEventOptions = {
|
|
18492
|
-
listItemScope?: UIListItemScope | null;
|
|
18493
|
-
instanceKey?: string;
|
|
18494
|
-
componentId?: UIComponentId;
|
|
18495
|
-
/** Resolved values by param id: the instance's own, falling back to the declared default. */
|
|
18496
|
-
componentParams?: Record<string, string>;
|
|
18497
|
-
eventControl?: BehaviorGraphEventControl;
|
|
18498
|
-
allowClosedScopeExecution?: boolean;
|
|
18499
|
-
};
|
|
18500
|
-
type UIHostAdapterBlueprintRuntime = {
|
|
18501
|
-
surfaceId: string;
|
|
18502
|
-
/** Instance-specific scope id. Defaults to `surfaceId` for top-level surfaces. */
|
|
18503
|
-
runtimeScopeId?: string;
|
|
18504
|
-
setSurfaceState: (key: string, value: unknown) => void;
|
|
18505
|
-
getSurfaceState: (key: string) => unknown;
|
|
18506
|
-
emitDebug: (event: BlueprintDebugEvent) => void;
|
|
18507
|
-
getSurfaceTransitionState?: () => {
|
|
18508
|
-
isEntering: boolean;
|
|
18509
|
-
isExiting: boolean;
|
|
18510
|
-
};
|
|
18511
|
-
/** Dispatch a widget private event slot (for example `init` or `mouseClick`) on the owner-local blueprint. */
|
|
18512
|
-
dispatchElementBlueprintEvent: (elementId: string, eventName: string, payload?: Record<string, unknown>, options?: UIHostAdapterElementEventOptions) => Promise<void>;
|
|
18513
|
-
/** Continue the current widget event from this element to its structural parent. */
|
|
18514
|
-
continueElementEventBubble?: (elementId: string, eventName: string, payload?: Record<string, unknown>, options?: UIHostAdapterElementEventOptions) => Promise<boolean>;
|
|
18515
|
-
/** Dispatch a surface-level event on the current surfaceMain blueprint. */
|
|
18516
|
-
dispatchSurfaceBlueprintEvent?: (eventName: string, payload?: Record<string, unknown>) => Promise<void>;
|
|
18517
|
-
/**
|
|
18518
|
-
* Raise one of this surface's declared input actions on its surfaceMain blueprint.
|
|
18519
|
-
*
|
|
18520
|
-
* The seam between routing and authoring: routing decides that this click, wheel or key means
|
|
18521
|
-
* "advance" on this surface (see `runtime/input/surfaceInputActions`), and this hands that
|
|
18522
|
-
* decision to the graph. Named rather than positional because the payload is what the action's
|
|
18523
|
-
* head node reads its pins from.
|
|
18524
|
-
*
|
|
18525
|
-
* It resolves when the action's graphs have run, which is what lets a lane walk stay sequential.
|
|
18526
|
-
*/
|
|
18527
|
-
dispatchSurfaceInputAction?: (payload: UIInputActionEventPayload) => Promise<void>;
|
|
18528
|
-
dispatchBroadcastEvent?: (eventName: string, data: unknown, sender?: string) => Promise<void>;
|
|
18529
|
-
getBroadcastListenerCount?: (eventName: string) => number;
|
|
18530
|
-
/** Invoke a declared blueprint fn (Call Fn node); awaits the fn body and returns its Fn Return values. */
|
|
18531
|
-
invokeBlueprintFn?: (input: {
|
|
18532
|
-
fnRef: string;
|
|
18533
|
-
args: Record<string, unknown>;
|
|
18534
|
-
depth: number;
|
|
18535
|
-
/** Surface of the calling execution; global callers omit it and only see global fns. */
|
|
18536
|
-
callerSurfaceId?: string;
|
|
18537
|
-
/** Component definition of the calling execution, when it is running inside one. */
|
|
18538
|
-
callerComponentId?: string;
|
|
18539
|
-
/** That instance's resolved params, which the fn body runs with. */
|
|
18540
|
-
callerComponentParams?: Record<string, string>;
|
|
18541
|
-
/** Which drawing the call came from, so the body's widget writes land on it. */
|
|
18542
|
-
callerInstanceKey?: string;
|
|
18543
|
-
signal?: AbortSignal;
|
|
18544
|
-
callerExecutionId?: string;
|
|
18545
|
-
}) => Promise<{
|
|
18546
|
-
returns: Record<string, unknown>;
|
|
18547
|
-
}>;
|
|
18548
|
-
frame?: {
|
|
18549
|
-
getParam: (key: string) => unknown;
|
|
18550
|
-
emit: (eventName: string, data: unknown) => Promise<void> | void;
|
|
18551
|
-
};
|
|
18552
|
-
/** M3-full: Dev Mode host API (graphs + TS ctx); absent in editor preview. */
|
|
18553
|
-
hostApi?: BlueprintHostApiRuntime;
|
|
18554
|
-
};
|
|
18555
|
-
type UIHostAdapter = {
|
|
18556
|
-
host: UIHost$1;
|
|
18557
|
-
navigate?: (target: unknown) => Promise<void> | void;
|
|
18558
|
-
resolveSlot?: (slotId: string) => {
|
|
18559
|
-
mount: (node: React$1.ReactNode) => void;
|
|
18560
|
-
} | null;
|
|
18561
|
-
gameUiRuntime?: {
|
|
18562
|
-
slotId: UIStageSlotId;
|
|
18563
|
-
};
|
|
18564
|
-
/**
|
|
18565
|
-
* M1 latch: which frozen BlueprintHostApiContract generation this adapter targets.
|
|
18566
|
-
* Does not imply all capabilities are implemented yet.
|
|
18567
|
-
*/
|
|
18568
|
-
blueprintHostApiVersion?: BlueprintHostApiContractVersion;
|
|
18569
|
-
/** M3-min: optional Blueprint runtime surface (Dev Mode). */
|
|
18570
|
-
blueprintRuntime?: UIHostAdapterBlueprintRuntime;
|
|
18571
|
-
/**
|
|
18572
|
-
* Story Action Blueprint runtime surface. Present only while a story-action blueprint graph
|
|
18573
|
-
* runs inside a compiled NLR `Script`; resolves scene/saved variable ids to their NLR backing
|
|
18574
|
-
* (`Scene.local` / `Storable`). Absent for UI blueprints.
|
|
18575
|
-
*/
|
|
18576
|
-
storyRuntime?: UIHostAdapterStoryRuntime;
|
|
18577
|
-
/** Editor preview: use the active workspace service instance for canvas-local interaction overrides. */
|
|
18578
|
-
editorStateService?: UIEditorStateService;
|
|
18579
|
-
/** Editor preview: use the active document service, including component-editor adapters. */
|
|
18580
|
-
editorDocumentService?: UIDocumentService;
|
|
18581
|
-
/**
|
|
18582
|
-
* Whether the surface this adapter renders is read-only right now (a frozen workspace).
|
|
18583
|
-
*
|
|
18584
|
-
* The two services above are the only thing a widget renderer needs in order to write the
|
|
18585
|
-
* document from inside its own markup, and the interaction layer's gesture table cannot reach
|
|
18586
|
-
* those handlers - a widget's `onDoubleClick` is attached by the widget, not by the canvas. So
|
|
18587
|
-
* the state travels on the adapter beside them, and {@link resolveInlineTextEditHost} is where
|
|
18588
|
-
* the two are read together.
|
|
18589
|
-
*/
|
|
18590
|
-
editorReadOnly?: UIEditorReadOnly;
|
|
18591
|
-
};
|
|
18592
|
-
type StoryVariableRuntimeAccess = {
|
|
18593
|
-
/** Resolve `variableId` to its stored value, or the declared default when unset. */
|
|
18594
|
-
get: (variableId: string) => unknown;
|
|
18595
|
-
/** Resolve `variableId` and write `value` to the backing store. */
|
|
18596
|
-
set: (variableId: string, value: unknown) => void;
|
|
18597
|
-
};
|
|
18598
|
-
type UIHostAdapterStoryRuntime = {
|
|
18599
|
-
sceneVar: StoryVariableRuntimeAccess;
|
|
18600
|
-
savedVar: StoryVariableRuntimeAccess;
|
|
18601
|
-
};
|
|
18602
16977
|
type BlueprintPinSemantic = "exec" | "data";
|
|
18603
16978
|
export type BlueprintNodePinDef = {
|
|
18604
16979
|
id: string;
|
|
@@ -18957,98 +17332,6 @@ interface IUIDocumentService extends IService {
|
|
|
18957
17332
|
};
|
|
18958
17333
|
renameElement(elementId: string, name: string): void;
|
|
18959
17334
|
}
|
|
18960
|
-
type InteractionOverride = {
|
|
18961
|
-
kind: "imageCrop";
|
|
18962
|
-
surfaceId: string;
|
|
18963
|
-
elementId: string;
|
|
18964
|
-
source: string;
|
|
18965
|
-
} | {
|
|
18966
|
-
kind: "textEdit";
|
|
18967
|
-
surfaceId: string;
|
|
18968
|
-
elementId: string;
|
|
18969
|
-
};
|
|
18970
|
-
type InteractionOverrideChange = {
|
|
18971
|
-
previous: InteractionOverride | null;
|
|
18972
|
-
next: InteractionOverride | null;
|
|
18973
|
-
};
|
|
18974
|
-
type UIEditorEnteredState = {
|
|
18975
|
-
surfaceId: string;
|
|
18976
|
-
elementId: string;
|
|
18977
|
-
variantId: string | null;
|
|
18978
|
-
};
|
|
18979
|
-
interface UIEditorStateEvents {
|
|
18980
|
-
toolChanged: UITool;
|
|
18981
|
-
viewportChanged: ViewportTransform;
|
|
18982
|
-
selectionChanged: SelectionState;
|
|
18983
|
-
interactionOverrideChanged: InteractionOverrideChange;
|
|
18984
|
-
/** Editor-only: which element is showing one of its states, and which; drives canvas preview. */
|
|
18985
|
-
enteredStateChanged: UIEditorEnteredState | null;
|
|
18986
|
-
/** Outline panel expand/collapse memory (persisted); payload unused. */
|
|
18987
|
-
outlineExpansionChanged: null;
|
|
18988
|
-
/** Outline panel chrome collapsed state (persisted). */
|
|
18989
|
-
outlinePanelCollapsedChanged: boolean;
|
|
18990
|
-
/** Smart snap / smart guides toggle (persisted in project settings). */
|
|
18991
|
-
smartSnapEnabledChanged: boolean;
|
|
18992
|
-
/** Per-category snap targets when smart snap is enabled (persisted). */
|
|
18993
|
-
smartSnapDetailSettingsChanged: SmartSnapDetailSettings;
|
|
18994
|
-
/** Ephemeral snap guide lines in surface space (viewport overlay). */
|
|
18995
|
-
snapGuidesChanged: ActiveSnapGuides | null;
|
|
18996
|
-
/** Screen-ratio preview frame preset id, `null` = off (pure view state, global settings). */
|
|
18997
|
-
previewAspectChanged: string | null;
|
|
18998
|
-
/** Safe-area preview frame device preset id, `null` = off (pure view state, global settings). */
|
|
18999
|
-
previewSafeAreaChanged: string | null;
|
|
19000
|
-
}
|
|
19001
|
-
interface IUIEditorStateService extends IService {
|
|
19002
|
-
getTool(): UITool;
|
|
19003
|
-
setTool(tool: UITool): void;
|
|
19004
|
-
getViewportTransform(): ViewportTransform;
|
|
19005
|
-
/** A hand gesture (zoom, pan, or a typed zoom); ends the fit mode the interface was following. */
|
|
19006
|
-
updateViewport(transform: Partial<ViewportTransform>): ViewportTransform;
|
|
19007
|
-
/** Which interface the current transform describes; `null` before any editor tab claimed it. */
|
|
19008
|
-
getViewportSurfaceId(): string | null;
|
|
19009
|
-
/** The fit mode in force, or `null` once the author moved the view by hand. */
|
|
19010
|
-
getViewportFit(): SurfaceViewportFit | null;
|
|
19011
|
-
/** Installs a computed zoom for an interface (stays live across resizes, unlike a hand gesture). */
|
|
19012
|
-
applyFittedViewport(surfaceId: string, transform: ViewportTransform, fit: SurfaceViewportFit): ViewportTransform;
|
|
19013
|
-
/** Restores a hand-set view (`null`), or returns the mode the caller must recompute. */
|
|
19014
|
-
adoptSurfaceViewport(surfaceId: string): SurfaceViewportFit | null;
|
|
19015
|
-
getSelection(): SelectionState;
|
|
19016
|
-
setSelection(selection: SelectionState): void;
|
|
19017
|
-
setUIElementSelection(selection: UIElementSelection): void;
|
|
19018
|
-
getDocument(): UIDocument;
|
|
19019
|
-
getSurface(surfaceId: string): UISurface | undefined;
|
|
19020
|
-
/** The state being shown on the canvas right now, or null while every element rests. */
|
|
19021
|
-
getEnteredState(): UIEditorEnteredState | null;
|
|
19022
|
-
setEnteredState(next: UIEditorEnteredState | null): void;
|
|
19023
|
-
/** Whether compact Border panel "sides" row is expanded (per element, persisted with project settings). */
|
|
19024
|
-
getAppearanceBorderSidesExpanded(elementId: string): boolean;
|
|
19025
|
-
setAppearanceBorderSidesExpanded(elementId: string, expanded: boolean): void;
|
|
19026
|
-
/** Outline: branch is collapsed when true (editor-only, project settings). */
|
|
19027
|
-
isOutlineBranchCollapsed(elementId: string): boolean;
|
|
19028
|
-
setOutlineBranchCollapsed(elementId: string, collapsed: boolean): void;
|
|
19029
|
-
/** Outline panel chrome: collapsed when true (editor-only global settings). */
|
|
19030
|
-
getOutlinePanelCollapsed(): boolean;
|
|
19031
|
-
setOutlinePanelCollapsed(collapsed: boolean): void;
|
|
19032
|
-
/** When true, dragging/resizing/inserting snaps to surface and sibling guides (project settings). */
|
|
19033
|
-
getSmartSnapEnabled(): boolean;
|
|
19034
|
-
setSmartSnapEnabled(enabled: boolean): void;
|
|
19035
|
-
/** Which guide categories participate when smart snap is on (persisted). */
|
|
19036
|
-
getSmartSnapDetailSettings(): SmartSnapDetailSettings;
|
|
19037
|
-
patchSmartSnapDetailSettings(patch: Partial<SmartSnapDetailSettings>): void;
|
|
19038
|
-
/**
|
|
19039
|
-
* Screen-ratio preview frame preset id (`null` = off). Pure view state: persisted in global
|
|
19040
|
-
* settings, never in the UIDocument, so toggling it cannot dirty the project.
|
|
19041
|
-
*/
|
|
19042
|
-
getPreviewAspectId(): string | null;
|
|
19043
|
-
setPreviewAspectId(aspectId: string | null): void;
|
|
19044
|
-
/** Safe-area preview frame device preset id (`null` = off). Pure view state, see above. */
|
|
19045
|
-
getPreviewSafeAreaId(): string | null;
|
|
19046
|
-
setPreviewSafeAreaId(safeAreaId: string | null): void;
|
|
19047
|
-
/** Active snap guides for the current interaction (null clears overlay). */
|
|
19048
|
-
getSnapGuides(): ActiveSnapGuides | null;
|
|
19049
|
-
setSnapGuides(guides: ActiveSnapGuides | null): void;
|
|
19050
|
-
on<K extends keyof UIEditorStateEvents>(event: K, handler: (data: UIEditorStateEvents[K]) => void): () => void;
|
|
19051
|
-
}
|
|
19052
17335
|
export type StoryPluginActionCreateInput = {
|
|
19053
17336
|
generateId: () => string;
|
|
19054
17337
|
initialText?: string;
|
|
@@ -19856,6 +18139,49 @@ export type RuntimePluginLocale = {
|
|
|
19856
18139
|
export type RuntimePluginMenu = {
|
|
19857
18140
|
set(spec: GameMenuSpec): Promise<void>;
|
|
19858
18141
|
};
|
|
18142
|
+
/**
|
|
18143
|
+
* What the engine's image cache is holding, against what it is allowed to hold. All sizes in bytes.
|
|
18144
|
+
*
|
|
18145
|
+
* Restated here rather than re-exported from the engine because a plugin cannot import
|
|
18146
|
+
* `narraleaf-react` - the only module specifiers it can resolve are `narraleaf-studio/*` and React.
|
|
18147
|
+
* The shape is the engine's `ImageCacheStats`; if that grows a field, this is the second place.
|
|
18148
|
+
*/
|
|
18149
|
+
export type RuntimePluginImageCacheStats = {
|
|
18150
|
+
/** Sources the cache holds a url for. */
|
|
18151
|
+
entries: number;
|
|
18152
|
+
/**
|
|
18153
|
+
* Bytes of fetched image data the cache is keeping alive.
|
|
18154
|
+
*
|
|
18155
|
+
* **Zero is a real answer, not a missing one.** A host that serves its own assets hands the
|
|
18156
|
+
* player urls instead of bytes, and then the player holds none: what the images cost lives in
|
|
18157
|
+
* the browser's cache, outside anything this can count. A reader that shows this as "memory
|
|
18158
|
+
* used" will report an improvement that did not happen - see {@link entries}, which still
|
|
18159
|
+
* counts, and the decoded figures below, which are the ones with a budget behind them.
|
|
18160
|
+
*/
|
|
18161
|
+
blobBytes: number;
|
|
18162
|
+
/** Sources whose decoded bitmap the cache is holding. */
|
|
18163
|
+
decodedEntries: number;
|
|
18164
|
+
/** Estimated size of those bitmaps, at width x height x 4 bytes each. */
|
|
18165
|
+
decodedBytes: number;
|
|
18166
|
+
/** Entries nothing may evict right now: shown by a mounted element, or pinned by the scene. */
|
|
18167
|
+
pinned: number;
|
|
18168
|
+
/** The budgets in force. `Infinity` where the game removed one. */
|
|
18169
|
+
budget: {
|
|
18170
|
+
blobBytes: number;
|
|
18171
|
+
decodedBytes: number;
|
|
18172
|
+
};
|
|
18173
|
+
};
|
|
18174
|
+
/**
|
|
18175
|
+
* `diagnostics` — what the player's caches weigh.
|
|
18176
|
+
*
|
|
18177
|
+
* Every member answers null before a game session exists, which is the ordinary state during
|
|
18178
|
+
* `setup()`. A plugin polls this; there is no change event, because a cache that announced every
|
|
18179
|
+
* eviction would cost more to watch than to run.
|
|
18180
|
+
*/
|
|
18181
|
+
export type RuntimePluginDiagnostics = {
|
|
18182
|
+
/** The engine's image cache, or null when no session is live. */
|
|
18183
|
+
imageCache(): RuntimePluginImageCacheStats | null;
|
|
18184
|
+
};
|
|
19859
18185
|
/** `assets` — turn an asset id from the pack into a URL this shell can load. */
|
|
19860
18186
|
export type RuntimePluginAssets = {
|
|
19861
18187
|
url(assetId: string): string;
|
|
@@ -19986,6 +18312,8 @@ export type RuntimePluginGame = {
|
|
|
19986
18312
|
menu?: RuntimePluginMenu;
|
|
19987
18313
|
/** Present with `"story.compile"`. */
|
|
19988
18314
|
story?: RuntimePluginStory;
|
|
18315
|
+
/** Present with `"diagnostics"`. */
|
|
18316
|
+
diagnostics?: RuntimePluginDiagnostics;
|
|
19989
18317
|
/** Present when `contributes.sidecars` is non-empty. */
|
|
19990
18318
|
sidecar?: RuntimePluginSidecars;
|
|
19991
18319
|
/** Present when `contributes.externalLinks` is non-empty. */
|
|
@@ -20006,6 +18334,163 @@ export type RuntimePluginDefinition = {
|
|
|
20006
18334
|
};
|
|
20007
18335
|
export declare function defineRuntimePlugin(definition: RuntimePluginDefinition): RuntimePluginDefinition;
|
|
20008
18336
|
export declare function isRuntimePluginDefinition(value: unknown): value is RuntimePluginDefinition;
|
|
18337
|
+
/**
|
|
18338
|
+
* The interface-editor extension surface a plugin actually gets.
|
|
18339
|
+
*
|
|
18340
|
+
* Studio's own widgets are described by `UIWidgetModule`, whose callbacks are handed the live
|
|
18341
|
+
* `UIDocumentService` and `UIEditorStateService`. Those are `Service` instances, and `getContext()`
|
|
18342
|
+
* on a service is public - so `documentService.getContext().services.get(...)` returns the workspace
|
|
18343
|
+
* service registry, and with it a `FileSystemService` that speaks to the main process under the
|
|
18344
|
+
* window's default privileged facade: recursive read and write over the author's whole project,
|
|
18345
|
+
* authorised as the window rather than as the plugin. That is the same escalation
|
|
18346
|
+
* `pluginWorkspaceGuard` closed on `ActionDefinition.onClick`, reached through the widget door.
|
|
18347
|
+
*
|
|
18348
|
+
* A class instance cannot be made safe by wrapping one method, either: `service.constructor` is the
|
|
18349
|
+
* real class, `Service` extends `Singleton`, and `Singleton.instances` is an ordinary static
|
|
18350
|
+
* property holding every service that has ever been constructed. Anything with that prototype chain
|
|
18351
|
+
* hands over the registry however many members are trapped on the way past.
|
|
18352
|
+
*
|
|
18353
|
+
* So the types below are what a widget is handed instead - plain objects with named methods,
|
|
18354
|
+
* built by `pluginWidgetGuard` and enforced there rather than here. **These declarations state the
|
|
18355
|
+
* contract; they do not impose it.** A plugin ships compiled JavaScript and can cast anything to
|
|
18356
|
+
* anything; the guard is what makes the cast find nothing.
|
|
18357
|
+
*
|
|
18358
|
+
* The surface is derived from what the built-in widgets do, which is the only honest measure of what
|
|
18359
|
+
* a widget needs: read the interface document, write the element's own props, layout, animation,
|
|
18360
|
+
* extra and list-item wiring, group a burst of those into one undo step, and move the selection.
|
|
18361
|
+
* Nothing here reaches outside `uidoc.json`.
|
|
18362
|
+
*/
|
|
18363
|
+
/**
|
|
18364
|
+
* Interface-document access for a plugin widget.
|
|
18365
|
+
*
|
|
18366
|
+
* Whole-document reads are deliberate: a structural widget cannot resolve its own parts without
|
|
18367
|
+
* looking them up, which is why the game side hands plugin renderers the document too. The document
|
|
18368
|
+
* is authored content the editor is already drawing, not a host power - and it is one document, not
|
|
18369
|
+
* an index that leads to unrelated resources.
|
|
18370
|
+
*
|
|
18371
|
+
* Writes are element-scoped by signature. They are not restricted to the element being inspected: a
|
|
18372
|
+
* widget with parts edits its parts, exactly as the built-in switch and list do, and there is no
|
|
18373
|
+
* honest way to tell "my part" from "someone else's element" from here.
|
|
18374
|
+
*/
|
|
18375
|
+
export type PluginWidgetDocumentApi = {
|
|
18376
|
+
/** The whole interface document, as the editor currently holds it. */
|
|
18377
|
+
getDocument(): UIDocument;
|
|
18378
|
+
/** A fresh element id, for a widget that builds child elements of its own. */
|
|
18379
|
+
generateId(): string;
|
|
18380
|
+
/** One component definition by id, for a widget that draws a linked component instance. */
|
|
18381
|
+
getComponent(componentId: string): UIComponentDefinition | undefined;
|
|
18382
|
+
createElement(parentId: string, type: string, layoutPatch?: Partial<UILayout>): UIElement;
|
|
18383
|
+
updateElementProps(elementId: string, propsPatch: Record<string, unknown>): void;
|
|
18384
|
+
updateElementExtra(elementId: string, extraPatch: Record<string, unknown>): void;
|
|
18385
|
+
updateElementLayout(elementId: string, layoutPatch: Partial<UILayout>, options?: {
|
|
18386
|
+
skipHistory?: boolean;
|
|
18387
|
+
}): void;
|
|
18388
|
+
updateElementAnimation(elementId: string, animation: UIPageAnimationSettings | null, options?: {
|
|
18389
|
+
mergeKey?: string;
|
|
18390
|
+
}): void;
|
|
18391
|
+
/** Collapse everything the callback writes into one undo entry on that surface. */
|
|
18392
|
+
runSurfaceHistoryTransaction(surfaceId: string, action: () => void): void;
|
|
18393
|
+
setListItemStructFields(elementId: string, fields: readonly UIStructField[]): void;
|
|
18394
|
+
setElementListItemFieldBinding(elementId: string, propPath: string, fieldId: string | null): void;
|
|
18395
|
+
ensureElementBlueprintValueBinding(elementId: string, propPath: string, input: {
|
|
18396
|
+
valueType: UIElementValueBindingValueType;
|
|
18397
|
+
displayName?: string;
|
|
18398
|
+
literalValue?: unknown;
|
|
18399
|
+
}): {
|
|
18400
|
+
blueprintId: string;
|
|
18401
|
+
};
|
|
18402
|
+
clearElementBlueprintValueBinding(elementId: string, propPath: string): void;
|
|
18403
|
+
};
|
|
18404
|
+
/**
|
|
18405
|
+
* Editor state a plugin widget's docker bar may read and move.
|
|
18406
|
+
*
|
|
18407
|
+
* Selection only. The interaction overrides (inline text edit, image crop) are not here because the
|
|
18408
|
+
* host honours them in built-in renderers alone - offering a plugin a switch that turns nothing on
|
|
18409
|
+
* would be worse than not having it.
|
|
18410
|
+
*/
|
|
18411
|
+
export type PluginWidgetEditorStateApi = {
|
|
18412
|
+
getSelection(): SelectionState;
|
|
18413
|
+
setUIElementSelection(selection: UIElementSelection): void;
|
|
18414
|
+
getEnteredState(): {
|
|
18415
|
+
surfaceId: string;
|
|
18416
|
+
elementId: string;
|
|
18417
|
+
variantId: string | null;
|
|
18418
|
+
} | null;
|
|
18419
|
+
setEnteredState(next: {
|
|
18420
|
+
surfaceId: string;
|
|
18421
|
+
elementId: string;
|
|
18422
|
+
variantId: string | null;
|
|
18423
|
+
} | null): void;
|
|
18424
|
+
};
|
|
18425
|
+
/** What a plugin widget's property fields read and write through. */
|
|
18426
|
+
export type PluginWidgetInspectorData = {
|
|
18427
|
+
element: UIElement;
|
|
18428
|
+
elements: UIElement[];
|
|
18429
|
+
documentService: PluginWidgetDocumentApi;
|
|
18430
|
+
surfaceId?: string;
|
|
18431
|
+
};
|
|
18432
|
+
export type PluginWidgetInspectorContext = {
|
|
18433
|
+
element: UIElement;
|
|
18434
|
+
documentService: PluginWidgetDocumentApi;
|
|
18435
|
+
};
|
|
18436
|
+
export type PluginWidgetDockerBarContext = {
|
|
18437
|
+
element: UIElement;
|
|
18438
|
+
documentService: PluginWidgetDocumentApi;
|
|
18439
|
+
stateService?: PluginWidgetEditorStateApi;
|
|
18440
|
+
surfaceId?: string;
|
|
18441
|
+
};
|
|
18442
|
+
export type PluginWidgetContextMenuContext = {
|
|
18443
|
+
element: UIElement;
|
|
18444
|
+
documentService: PluginWidgetDocumentApi;
|
|
18445
|
+
surfaceId: string;
|
|
18446
|
+
};
|
|
18447
|
+
export type PluginWidgetFloatingToolbarContext = {
|
|
18448
|
+
element: UIElement;
|
|
18449
|
+
documentService: PluginWidgetDocumentApi;
|
|
18450
|
+
surfaceId: string;
|
|
18451
|
+
openSurfaceEditor?: (surfaceId: string) => void;
|
|
18452
|
+
};
|
|
18453
|
+
export type PluginWidgetLayoutSizeFieldContext = {
|
|
18454
|
+
element: UIElement;
|
|
18455
|
+
documentService: PluginWidgetDocumentApi;
|
|
18456
|
+
surfaceId?: string;
|
|
18457
|
+
primaryId: string;
|
|
18458
|
+
};
|
|
18459
|
+
/**
|
|
18460
|
+
* A widget type contributed by a plugin.
|
|
18461
|
+
*
|
|
18462
|
+
* `render` takes the same {@link RuntimeWidgetRendererProps} the game hands a plugin renderer,
|
|
18463
|
+
* rather than the editor's wider props: one render function, drawn the same way in both places, and
|
|
18464
|
+
* no `hostAdapter` on either side. See `create-plugin.md` for the shared-module pattern that relies
|
|
18465
|
+
* on it.
|
|
18466
|
+
*
|
|
18467
|
+
* `registerBlueprintNodes` is absent on purpose. It exists on the built-in module type and the host
|
|
18468
|
+
* only ever calls it for built-ins; a plugin registers nodes through `app.services.blueprintNodes`,
|
|
18469
|
+
* where the execute context is narrowed the same way this is.
|
|
18470
|
+
*/
|
|
18471
|
+
export type PluginWidgetModule = {
|
|
18472
|
+
/** Unique type id; must start with the plugin id and be declared in `contributes.widgets`. */
|
|
18473
|
+
readonly type: string;
|
|
18474
|
+
/** Widget type this one specialises. */
|
|
18475
|
+
readonly extends?: string;
|
|
18476
|
+
/** Event and effect capabilities, shared with the blueprint tooling. */
|
|
18477
|
+
readonly logicApi?: WidgetLogicApi;
|
|
18478
|
+
readonly displayName: string;
|
|
18479
|
+
readonly icon: LucideIcon;
|
|
18480
|
+
createDefaultElement(): Partial<UIElement>;
|
|
18481
|
+
createDefaultChildElements?(context: DefaultChildElementContext): DefaultChildElementResult;
|
|
18482
|
+
listEditorStates?(element: UIElement): {
|
|
18483
|
+
id: string | null;
|
|
18484
|
+
name: string;
|
|
18485
|
+
}[];
|
|
18486
|
+
render(props: RuntimeWidgetRendererProps): React$1.ReactElement | null;
|
|
18487
|
+
createInspector?(context: PluginWidgetInspectorContext): PropertyEditorSchema<PluginWidgetInspectorData> | undefined;
|
|
18488
|
+
createDockerBarItems?(context: PluginWidgetDockerBarContext): DockerBarItem[];
|
|
18489
|
+
createMultiSelectDockerBarItems?(context: PluginWidgetDockerBarContext): DockerBarItem[];
|
|
18490
|
+
createContextMenuItems?(context: PluginWidgetContextMenuContext): ContextMenuItemDef[];
|
|
18491
|
+
createFloatingToolbarItems?(context: PluginWidgetFloatingToolbarContext): FloatingToolbarItem[];
|
|
18492
|
+
createLayoutSizeField?(context: PluginWidgetLayoutSizeFieldContext): FieldDefinition<PluginWidgetInspectorData> | null | undefined;
|
|
18493
|
+
};
|
|
20009
18494
|
/**
|
|
20010
18495
|
* Caller-defined section (e.g. built-in presets) shown as a collapsible group in the asset list.
|
|
20011
18496
|
* Workspace filter chips do not apply; only the search box filters `assets` (same rules as project assets).
|
|
@@ -20561,6 +19046,20 @@ declare const pluginUi: Readonly<{
|
|
|
20561
19046
|
}>;
|
|
20562
19047
|
}>;
|
|
20563
19048
|
export type PluginUiKit = typeof pluginUi;
|
|
19049
|
+
/**
|
|
19050
|
+
* What a plugin can learn about a widget type it did not register.
|
|
19051
|
+
*
|
|
19052
|
+
* The registry itself holds host objects, so what comes back is the answer to the question a plugin
|
|
19053
|
+
* can act on - does this type exist, and what is it called - rather than the module behind it.
|
|
19054
|
+
*/
|
|
19055
|
+
export type PluginWidgetTypeInfo = {
|
|
19056
|
+
type: string;
|
|
19057
|
+
displayName: string;
|
|
19058
|
+
/** The widget type this one specialises, when it specialises one. */
|
|
19059
|
+
extends?: string;
|
|
19060
|
+
/** The plugin that contributed it, absent for Studio's own widgets. */
|
|
19061
|
+
ownerPluginId?: string;
|
|
19062
|
+
};
|
|
20564
19063
|
/**
|
|
20565
19064
|
* A blueprint node as a *plugin* writes it: everything a node declares about itself, with the
|
|
20566
19065
|
* narrowed execute of `narraleaf-studio/runtime`.
|
|
@@ -20812,7 +19311,7 @@ export type PluginAssetsService = {
|
|
|
20812
19311
|
revokeObjectUrl(url: string): void;
|
|
20813
19312
|
};
|
|
20814
19313
|
/** An active editor locale code (built-in like "en"/"zh", or a plugin-provided locale). */
|
|
20815
|
-
type LocaleCode
|
|
19314
|
+
export type LocaleCode = string;
|
|
20816
19315
|
/**
|
|
20817
19316
|
* A plugin's own message tables: `locale code -> (message key -> string)`. This
|
|
20818
19317
|
* is the plugin's private catalog, unrelated to Studio's own translations.
|
|
@@ -20832,7 +19331,7 @@ export type PluginMessageBundle = {
|
|
|
20832
19331
|
* {@link PluginI18n.onLocaleChange} to re-render on a language switch.
|
|
20833
19332
|
*/
|
|
20834
19333
|
export type PluginTranslator = {
|
|
20835
|
-
readonly locale: LocaleCode
|
|
19334
|
+
readonly locale: LocaleCode;
|
|
20836
19335
|
t(key: string, params?: Record<string, string | number>): string;
|
|
20837
19336
|
};
|
|
20838
19337
|
/**
|
|
@@ -20842,14 +19341,14 @@ export type PluginTranslator = {
|
|
|
20842
19341
|
*/
|
|
20843
19342
|
export type PluginI18n = {
|
|
20844
19343
|
/** The editor's active locale code. */
|
|
20845
|
-
readonly locale: LocaleCode
|
|
19344
|
+
readonly locale: LocaleCode;
|
|
20846
19345
|
/**
|
|
20847
19346
|
* Subscribe to editor-language changes. The listener fires with the new
|
|
20848
19347
|
* locale code whenever the active editor language changes. Returns a
|
|
20849
19348
|
* {@link PluginCleanup} (also tracked by the host, so it is reclaimed on
|
|
20850
19349
|
* unload even if you forget to call it).
|
|
20851
19350
|
*/
|
|
20852
|
-
onLocaleChange(listener: (locale: LocaleCode
|
|
19351
|
+
onLocaleChange(listener: (locale: LocaleCode) => void): PluginCleanup;
|
|
20853
19352
|
/** Locale-aware number formatting bound to the editor's active locale. */
|
|
20854
19353
|
formatNumber(value: number, options?: Intl.NumberFormatOptions): string;
|
|
20855
19354
|
/** Locale-aware date formatting bound to the editor's active locale. */
|
|
@@ -20983,11 +19482,18 @@ export type PluginServices = {
|
|
|
20983
19482
|
error(message: string): void;
|
|
20984
19483
|
};
|
|
20985
19484
|
};
|
|
19485
|
+
/**
|
|
19486
|
+
* Contribute a widget type to the interface editor; see {@link PluginWidgetModule}.
|
|
19487
|
+
*
|
|
19488
|
+
* `get` and `list` answer with a type's name rather than with its module. A widget module is
|
|
19489
|
+
* the host's own object - Studio's built-ins carry the editor services in their callbacks - and
|
|
19490
|
+
* "which types exist" is the whole of what a plugin can act on.
|
|
19491
|
+
*/
|
|
20986
19492
|
widgets: {
|
|
20987
|
-
register(module:
|
|
20988
|
-
registerMany(modules:
|
|
20989
|
-
get(type: string):
|
|
20990
|
-
list():
|
|
19493
|
+
register(module: PluginWidgetModule): PluginCleanup;
|
|
19494
|
+
registerMany(modules: PluginWidgetModule[]): PluginCleanup;
|
|
19495
|
+
get(type: string): PluginWidgetTypeInfo | undefined;
|
|
19496
|
+
list(): PluginWidgetTypeInfo[];
|
|
20991
19497
|
has(type: string): boolean;
|
|
20992
19498
|
};
|
|
20993
19499
|
story: {
|
|
@@ -21036,7 +19542,6 @@ export declare function isPluginDefinition(value: unknown): value is PluginDefin
|
|
|
21036
19542
|
|
|
21037
19543
|
export {
|
|
21038
19544
|
BehaviorNodeExecuteResult as RuntimeBlueprintNodeResult,
|
|
21039
|
-
LocaleCode$1 as LocaleCode,
|
|
21040
19545
|
SelectOption$1 as SelectOption,
|
|
21041
19546
|
};
|
|
21042
19547
|
|