@xenosystem/blocks 0.11.6 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/time/index.d.ts +166 -5
- package/dist/time/index.js +258 -85
- package/package.json +5 -5
package/dist/time/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PanelHost, PanelModule, PanelManifest } from '@xenosystem/block-sdk';
|
|
1
|
+
import { PanelHost, PanelModule, PanelManifest, BlockDeclaration } from '@xenosystem/block-sdk';
|
|
2
2
|
import { ThrottleClock, XenoPlayheadClock, XenoTimebase, XenoTransportState, XenoTick, XenoStepUnit, XenoLoopRange } from '@xenosystem/time-core';
|
|
3
3
|
export { BAR_SUBDIVISION, BarsBeats, DEFAULT_TIMEBASE, DISPLAY_CYCLE, ExtrapolateInput, IDLE_CLOCK, ThrottleClock, Throttled, XenoLoopRange, XenoPlayheadClock, XenoStepUnit, XenoTempoEntry, XenoTick, XenoTimeDisplay, XenoTimeSignature, XenoTimebase, XenoTransportIntent, XenoTransportState, clampTick, clockAt, createThrottle, displayLabel, effectiveFps, extrapolateTick, formatBars, formatFrames, formatSeconds, formatTick, formatTimecode, frameToTick, isAnimating, nextDisplay, normalizeClock, normalizeTimebase, secondsToTicks, tickToFrame, ticksToBarsBeats, ticksToSeconds, toTick, wrapIntoLoop } from '@xenosystem/time-core';
|
|
4
4
|
import { ReactElement, ReactNode } from 'react';
|
|
@@ -208,7 +208,15 @@ declare function ticksPerStep(unit: XenoStepUnit, timebase: XenoTimebase): numbe
|
|
|
208
208
|
*/
|
|
209
209
|
|
|
210
210
|
/** Options for {@link createTransportPanel}. */
|
|
211
|
-
|
|
211
|
+
interface CreateTransportPanelOptions extends TransportPanelControllerOptions {
|
|
212
|
+
/**
|
|
213
|
+
* Draw the strip yourself — a host that mounts the block AS ITS DECLARATION renders
|
|
214
|
+
* `TRANSPORT_DECLARATION` from `transportViewState(controller)` here and applies `ui` intents with
|
|
215
|
+
* `applyTransportUi`. Default: the code view. The RAF pump and the keyboard model stay with the
|
|
216
|
+
* controller either way: `controller.pump()` while `isAnimating()`, `controller.handleKey()` on the root.
|
|
217
|
+
*/
|
|
218
|
+
render?: (root: HTMLElement, controller: TransportPanelController) => () => void;
|
|
219
|
+
}
|
|
212
220
|
/**
|
|
213
221
|
* Build the Transport panel module.
|
|
214
222
|
*
|
|
@@ -239,8 +247,9 @@ declare const transportManifest: PanelManifest;
|
|
|
239
247
|
* transport is not moving. That is the whole 60fps-without-streaming trick — no per-frame IPC, no
|
|
240
248
|
* idle wakeups.
|
|
241
249
|
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
250
|
+
* It draws the same model as `TRANSPORT_DECLARATION` (`transportPanelView(transportViewState(c))`);
|
|
251
|
+
* the declaration test holds the two byte-identical. The scrub gesture arrives from the Slider as a
|
|
252
|
+
* FRACTION and is mapped to a tick by the controller, exactly as the declaration's `ui` intent is.
|
|
244
253
|
*
|
|
245
254
|
* @module
|
|
246
255
|
*/
|
|
@@ -251,6 +260,158 @@ interface TransportPanelViewProps {
|
|
|
251
260
|
}
|
|
252
261
|
declare function TransportPanelView({ controller }: TransportPanelViewProps): ReactElement;
|
|
253
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Inline transport glyphs at lucide geometry, **strokeWidth 1.5** (DESIGN_SYSTEM §6). Zero runtime
|
|
265
|
+
* dependencies — no `lucide-react` import. Shapes are rectangles and triangles only; the record
|
|
266
|
+
* glyph is a rounded SQUARE, never a circle (§3 "no circles anywhere").
|
|
267
|
+
*
|
|
268
|
+
* @module
|
|
269
|
+
*/
|
|
270
|
+
|
|
271
|
+
interface IconProps {
|
|
272
|
+
size?: number;
|
|
273
|
+
}
|
|
274
|
+
/** lucide `play` (filled for weight at small sizes). */
|
|
275
|
+
declare function PlayIcon({ size }: IconProps): ReactElement;
|
|
276
|
+
/** lucide `pause`. */
|
|
277
|
+
declare function PauseIcon({ size }: IconProps): ReactElement;
|
|
278
|
+
/** lucide `square` — stop. */
|
|
279
|
+
declare function StopIcon({ size }: IconProps): ReactElement;
|
|
280
|
+
/** Record — a rounded SQUARE (the XENO shape language has no circles). */
|
|
281
|
+
declare function RecordIcon({ size }: IconProps): ReactElement;
|
|
282
|
+
/** lucide `skip-back` — go to start. */
|
|
283
|
+
declare function StartIcon({ size }: IconProps): ReactElement;
|
|
284
|
+
/** lucide `skip-forward` — go to end. */
|
|
285
|
+
declare function EndIcon({ size }: IconProps): ReactElement;
|
|
286
|
+
/** Step one unit back. */
|
|
287
|
+
declare function StepBackIcon({ size }: IconProps): ReactElement;
|
|
288
|
+
/** Step one unit forward. */
|
|
289
|
+
declare function StepForwardIcon({ size }: IconProps): ReactElement;
|
|
290
|
+
/** lucide `rewind` — shuttle reverse. */
|
|
291
|
+
declare function ShuttleLeftIcon({ size }: IconProps): ReactElement;
|
|
292
|
+
/** lucide `fast-forward` — shuttle forward. */
|
|
293
|
+
declare function ShuttleRightIcon({ size }: IconProps): ReactElement;
|
|
294
|
+
/** lucide `repeat` — loop. */
|
|
295
|
+
declare function LoopIcon({ size }: IconProps): ReactElement;
|
|
296
|
+
/** A metronome pendulum. */
|
|
297
|
+
declare function MetronomeIcon({ size }: IconProps): ReactElement;
|
|
298
|
+
/** Play or pause, decided by a prop — one node in a declaration instead of two switched by `when`. */
|
|
299
|
+
declare function PlayPauseIcon({ playing, size }: {
|
|
300
|
+
playing?: boolean;
|
|
301
|
+
size?: number;
|
|
302
|
+
}): ReactElement;
|
|
303
|
+
/**
|
|
304
|
+
* The glyphs by registry name, for a declaration (`transport/PlayIcon`). Block-local until the
|
|
305
|
+
* elements icon set lands, then these resolve to `icons/*` and this map goes.
|
|
306
|
+
*/
|
|
307
|
+
declare const TRANSPORT_ICONS: {
|
|
308
|
+
'transport/PlayIcon': typeof PlayIcon;
|
|
309
|
+
'transport/PauseIcon': typeof PauseIcon;
|
|
310
|
+
'transport/PlayPauseIcon': typeof PlayPauseIcon;
|
|
311
|
+
'transport/StopIcon': typeof StopIcon;
|
|
312
|
+
'transport/RecordIcon': typeof RecordIcon;
|
|
313
|
+
'transport/StartIcon': typeof StartIcon;
|
|
314
|
+
'transport/EndIcon': typeof EndIcon;
|
|
315
|
+
'transport/StepBackIcon': typeof StepBackIcon;
|
|
316
|
+
'transport/StepForwardIcon': typeof StepForwardIcon;
|
|
317
|
+
'transport/ShuttleLeftIcon': typeof ShuttleLeftIcon;
|
|
318
|
+
'transport/ShuttleRightIcon': typeof ShuttleRightIcon;
|
|
319
|
+
'transport/LoopIcon': typeof LoopIcon;
|
|
320
|
+
'transport/MetronomeIcon': typeof MetronomeIcon;
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* The transport strip AS A DECLARATION — the fourth block written the §8d way (auth gate, agent,
|
|
325
|
+
* account, transport), and the first whose runtime is a real-time controller.
|
|
326
|
+
*
|
|
327
|
+
* Presentation contract: input `view` (a {@link TransportViewState} the runtime derives from the
|
|
328
|
+
* controller on every change and every animation frame), output `ui` (a {@link TransportUiIntent}),
|
|
329
|
+
* applied by the runtime to the controller's own methods. The declaration holds no state and does no
|
|
330
|
+
* time maths: the readout, the progress and the ARIA triple arrive already computed, and a scrub is
|
|
331
|
+
* a FRACTION of the track (the slider owns its geometry; `fractionToTick` stays in the controller).
|
|
332
|
+
*
|
|
333
|
+
* The code view (`TransportPanelView`) renders the same model through `transportPanelView`; the
|
|
334
|
+
* test holds the two byte-identical in every state the controller can be driven into.
|
|
335
|
+
*/
|
|
336
|
+
|
|
337
|
+
/** What the runtime pushes on `view` — everything the strip shows, already formatted. */
|
|
338
|
+
interface TransportViewState {
|
|
339
|
+
playing: boolean;
|
|
340
|
+
recording: boolean;
|
|
341
|
+
loopEnabled: boolean;
|
|
342
|
+
metronome: boolean;
|
|
343
|
+
punch: boolean;
|
|
344
|
+
bpm: number;
|
|
345
|
+
show: {
|
|
346
|
+
shuttle: boolean;
|
|
347
|
+
record: boolean;
|
|
348
|
+
loop: boolean;
|
|
349
|
+
metronome: boolean;
|
|
350
|
+
punch: boolean;
|
|
351
|
+
bpm: boolean;
|
|
352
|
+
inOut: boolean;
|
|
353
|
+
scrubber: boolean;
|
|
354
|
+
};
|
|
355
|
+
readout: string;
|
|
356
|
+
displayLabel: string;
|
|
357
|
+
durationReadout: string;
|
|
358
|
+
progress: number;
|
|
359
|
+
duration: number;
|
|
360
|
+
currentTick: number;
|
|
361
|
+
}
|
|
362
|
+
type TransportUiIntent = {
|
|
363
|
+
kind: 'goToStart';
|
|
364
|
+
} | {
|
|
365
|
+
kind: 'stepBack';
|
|
366
|
+
} | {
|
|
367
|
+
kind: 'shuttleBack';
|
|
368
|
+
} | {
|
|
369
|
+
kind: 'togglePlay';
|
|
370
|
+
} | {
|
|
371
|
+
kind: 'stop';
|
|
372
|
+
} | {
|
|
373
|
+
kind: 'shuttleForward';
|
|
374
|
+
} | {
|
|
375
|
+
kind: 'stepForward';
|
|
376
|
+
} | {
|
|
377
|
+
kind: 'goToEnd';
|
|
378
|
+
} | {
|
|
379
|
+
kind: 'record';
|
|
380
|
+
} | {
|
|
381
|
+
kind: 'toggleLoop';
|
|
382
|
+
} | {
|
|
383
|
+
kind: 'toggleMetronome';
|
|
384
|
+
} | {
|
|
385
|
+
kind: 'cycleDisplay';
|
|
386
|
+
} | {
|
|
387
|
+
kind: 'setTempo';
|
|
388
|
+
bpm: number;
|
|
389
|
+
} | {
|
|
390
|
+
kind: 'setIn';
|
|
391
|
+
} | {
|
|
392
|
+
kind: 'setOut';
|
|
393
|
+
} | {
|
|
394
|
+
kind: 'scrub';
|
|
395
|
+
fraction: number;
|
|
396
|
+
phase: 'begin' | 'move' | 'end' | 'cancel';
|
|
397
|
+
};
|
|
398
|
+
/** Derive the view state from the live controller — the runtime calls this on every draw. */
|
|
399
|
+
declare function transportViewState(c: TransportPanelController): TransportViewState;
|
|
400
|
+
/** Apply a `ui` intent to the controller — the runtime's half of the contract. */
|
|
401
|
+
declare function applyTransportUi(c: TransportPanelController, intent: TransportUiIntent): void;
|
|
402
|
+
declare const transportViewManifest: PanelManifest;
|
|
403
|
+
/** The view model both renderers draw from: the state plus every derived label. */
|
|
404
|
+
interface TransportPanelViewModel extends TransportViewState {
|
|
405
|
+
stopped: boolean;
|
|
406
|
+
playLabel: string;
|
|
407
|
+
positionLabel: string;
|
|
408
|
+
}
|
|
409
|
+
declare function transportPanelView(state: TransportViewState): TransportPanelViewModel;
|
|
410
|
+
declare const BEHAVIOURS: {
|
|
411
|
+
'time/transportPanelView': (inputs: Record<string, unknown>) => TransportPanelViewModel;
|
|
412
|
+
};
|
|
413
|
+
declare const TRANSPORT_DECLARATION: BlockDeclaration;
|
|
414
|
+
|
|
254
415
|
/**
|
|
255
416
|
* `XenoTimeScale` — **the only thing in this package that converts between pixels and ticks.**
|
|
256
417
|
*
|
|
@@ -2258,4 +2419,4 @@ interface CalendarPanelViewProps {
|
|
|
2258
2419
|
/** The Calendar panel view. */
|
|
2259
2420
|
declare function CalendarPanelView({ controller, firstDayOfWeek, emptyHint, }: CalendarPanelViewProps): ReactNode;
|
|
2260
2421
|
|
|
2261
|
-
export { ALL_CALENDAR_MODES, type BeginDragOptions, type BuildCellsOptions, CALENDAR_PANEL_ID, CalendarController, type CalendarControllerOptions, type CalendarHostBridge, type CalendarPanelState, CalendarPanelView, type CalendarPanelViewProps, type CalendarRenderContext, type CalendarViewState, type CreateCalendarPanelOptions, type CreateTimelinePanelOptions, type CreateTransportPanelOptions, DEFAULT_SNAP, DEFAULT_ZOOM, DRAG_THRESHOLD_PX, type DeriveOptions, EDGE_ZONE_MIN_CLIP_PX, EDGE_ZONE_PX, MIN_MAJOR_PX, MIN_MINOR_PX, TIMELINE_PANEL_ID, TRIM_SNAP_PX, TimelineController, type TimelineControllerOptions, type TimelineHostBridge, type TimelinePanelState, TimelinePanelView, type TimelinePanelViewProps, type TimelineRenderConfig, type TimelineRenderContext, type TimelineViewState, type TransportKeyEvent, TransportPanelController, type TransportPanelControllerOptions, type TransportPanelSerialized, TransportPanelView, type TransportPanelViewProps, type XenoArrangement, type XenoCachedTile, type XenoCalendarCell, type XenoCalendarEdit, type XenoCalendarEvent, type XenoCalendarSlotActivate, type XenoCalendarViewMode, type XenoCalendarWindow, type XenoClip, type XenoClipFade, type XenoDragKind, type XenoDragModifiers, type XenoDragPreview, type XenoDragState, type XenoHitTarget, type XenoLaneTile, type XenoLaneTileRequest, type XenoMarker, type XenoOverlaySpan, type XenoRenderTier, type XenoRowLayout, type XenoRulerTick, type XenoSnapCandidate, type XenoSnapConfig, type XenoSnapMode, type XenoSnapResult, type XenoTickWeight, XenoTileCache, type XenoTileCacheOptions, XenoTimeScale, type XenoTimeScaleGeometry, type XenoTimeScaleState, type XenoTimelineOp, type XenoTimelineSelection, type XenoTimelineTool, type XenoTimelineViewport, type XenoTrack, type XenoTrackKind, type XenoTrimMode, type XenoVisibleTrack, type XenoZoomBounds, addDays, addMonths, alignToTileGrid, beginDrag, blitTile, buildCells, buildRowLayout, calendarManifest, calendarPanel, chooseRung, clampScroll, clipDuration, clipsInMarquee, clipsOverlap, collectSnapTargets, commitDrag, computeVisible, createCalendarPanel, createTimelinePanel, createTransportPanel, dayKey, daysInMonth, dedupeByColumn, deriveEvents, edgeZone, gridStart, gridTicksFor, hasSourceWindow, isZoomGesture, isoWeekday, packOverlaps, parseDayKey, passedThreshold, previewDrag, renderTier, rowAtY, rowInWindow, rulerTicks, scrollToReveal, snapDelta, snapTick, snapWouldFight, sourceRangeFor, statusTone, ticksPerStep, tileKey, tileWidthTicks, timelineManifest, timelinePanel, todayKey, transportManifest, transportPanel, trimModeFor, visibleClips, visibleRows, weekStart, wheelZoomFactor, withSnapModifier, zoomAboutCursor, zoomBucket, zoomToFit };
|
|
2422
|
+
export { ALL_CALENDAR_MODES, type BeginDragOptions, type BuildCellsOptions, CALENDAR_PANEL_ID, CalendarController, type CalendarControllerOptions, type CalendarHostBridge, type CalendarPanelState, CalendarPanelView, type CalendarPanelViewProps, type CalendarRenderContext, type CalendarViewState, type CreateCalendarPanelOptions, type CreateTimelinePanelOptions, type CreateTransportPanelOptions, DEFAULT_SNAP, DEFAULT_ZOOM, DRAG_THRESHOLD_PX, type DeriveOptions, EDGE_ZONE_MIN_CLIP_PX, EDGE_ZONE_PX, MIN_MAJOR_PX, MIN_MINOR_PX, TIMELINE_PANEL_ID, BEHAVIOURS as TRANSPORT_BEHAVIOURS, TRANSPORT_DECLARATION, TRANSPORT_ICONS, TRIM_SNAP_PX, TimelineController, type TimelineControllerOptions, type TimelineHostBridge, type TimelinePanelState, TimelinePanelView, type TimelinePanelViewProps, type TimelineRenderConfig, type TimelineRenderContext, type TimelineViewState, type TransportKeyEvent, TransportPanelController, type TransportPanelControllerOptions, type TransportPanelSerialized, TransportPanelView, type TransportPanelViewModel, type TransportPanelViewProps, type TransportUiIntent, type TransportViewState, type XenoArrangement, type XenoCachedTile, type XenoCalendarCell, type XenoCalendarEdit, type XenoCalendarEvent, type XenoCalendarSlotActivate, type XenoCalendarViewMode, type XenoCalendarWindow, type XenoClip, type XenoClipFade, type XenoDragKind, type XenoDragModifiers, type XenoDragPreview, type XenoDragState, type XenoHitTarget, type XenoLaneTile, type XenoLaneTileRequest, type XenoMarker, type XenoOverlaySpan, type XenoRenderTier, type XenoRowLayout, type XenoRulerTick, type XenoSnapCandidate, type XenoSnapConfig, type XenoSnapMode, type XenoSnapResult, type XenoTickWeight, XenoTileCache, type XenoTileCacheOptions, XenoTimeScale, type XenoTimeScaleGeometry, type XenoTimeScaleState, type XenoTimelineOp, type XenoTimelineSelection, type XenoTimelineTool, type XenoTimelineViewport, type XenoTrack, type XenoTrackKind, type XenoTrimMode, type XenoVisibleTrack, type XenoZoomBounds, addDays, addMonths, alignToTileGrid, applyTransportUi, beginDrag, blitTile, buildCells, buildRowLayout, calendarManifest, calendarPanel, chooseRung, clampScroll, clipDuration, clipsInMarquee, clipsOverlap, collectSnapTargets, commitDrag, computeVisible, createCalendarPanel, createTimelinePanel, createTransportPanel, dayKey, daysInMonth, dedupeByColumn, deriveEvents, edgeZone, gridStart, gridTicksFor, hasSourceWindow, isZoomGesture, isoWeekday, packOverlaps, parseDayKey, passedThreshold, previewDrag, renderTier, rowAtY, rowInWindow, rulerTicks, scrollToReveal, snapDelta, snapTick, snapWouldFight, sourceRangeFor, statusTone, ticksPerStep, tileKey, tileWidthTicks, timelineManifest, timelinePanel, todayKey, transportManifest, transportPanel, transportPanelView, transportViewManifest, transportViewState, trimModeFor, visibleClips, visibleRows, weekStart, wheelZoomFactor, withSnapModifier, zoomAboutCursor, zoomBucket, zoomToFit };
|
package/dist/time/index.js
CHANGED
|
@@ -782,6 +782,209 @@ function ticksPerStep(unit, timebase) {
|
|
|
782
782
|
import { useCallback, useEffect, useRef, useSyncExternalStore } from "react";
|
|
783
783
|
import { Column, IconButton, NumberInput, Readout, Slider, Stack, TextButton } from "@xenosystem/components/chrome";
|
|
784
784
|
|
|
785
|
+
// src/time/transport/declaration.ts
|
|
786
|
+
function transportViewState(c) {
|
|
787
|
+
const state = c.getState();
|
|
788
|
+
return {
|
|
789
|
+
playing: c.isPlaying(),
|
|
790
|
+
recording: !!state.recording,
|
|
791
|
+
loopEnabled: !!state.loopEnabled,
|
|
792
|
+
metronome: !!state.metronome,
|
|
793
|
+
punch: !!state.punch,
|
|
794
|
+
bpm: state.bpm ?? 120,
|
|
795
|
+
show: {
|
|
796
|
+
shuttle: c.showsControl("shuttle"),
|
|
797
|
+
record: c.showsControl("record"),
|
|
798
|
+
loop: c.showsControl("loop"),
|
|
799
|
+
metronome: c.showsControl("metronome"),
|
|
800
|
+
punch: c.showsControl("punch"),
|
|
801
|
+
bpm: c.showsControl("bpm"),
|
|
802
|
+
inOut: c.showsControl("inOut"),
|
|
803
|
+
scrubber: c.showsControl("scrubber")
|
|
804
|
+
},
|
|
805
|
+
readout: c.getReadout(),
|
|
806
|
+
displayLabel: (0, format_exports.displayLabel)(c.getDisplay()),
|
|
807
|
+
durationReadout: c.getDurationReadout(),
|
|
808
|
+
progress: c.getProgress(),
|
|
809
|
+
duration: c.getDuration(),
|
|
810
|
+
currentTick: c.getCurrentTick()
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
function applyTransportUi(c, intent) {
|
|
814
|
+
switch (intent.kind) {
|
|
815
|
+
case "goToStart":
|
|
816
|
+
c.goToStart();
|
|
817
|
+
break;
|
|
818
|
+
case "stepBack":
|
|
819
|
+
c.step(-1);
|
|
820
|
+
break;
|
|
821
|
+
case "shuttleBack":
|
|
822
|
+
c.shuttleStep(-1);
|
|
823
|
+
break;
|
|
824
|
+
case "togglePlay":
|
|
825
|
+
c.togglePlay();
|
|
826
|
+
break;
|
|
827
|
+
case "stop":
|
|
828
|
+
c.stop();
|
|
829
|
+
break;
|
|
830
|
+
case "shuttleForward":
|
|
831
|
+
c.shuttleStep(1);
|
|
832
|
+
break;
|
|
833
|
+
case "stepForward":
|
|
834
|
+
c.step(1);
|
|
835
|
+
break;
|
|
836
|
+
case "goToEnd":
|
|
837
|
+
c.goToEnd();
|
|
838
|
+
break;
|
|
839
|
+
case "record":
|
|
840
|
+
c.record();
|
|
841
|
+
break;
|
|
842
|
+
case "toggleLoop":
|
|
843
|
+
c.toggleLoop();
|
|
844
|
+
break;
|
|
845
|
+
case "toggleMetronome":
|
|
846
|
+
c.toggleMetronome();
|
|
847
|
+
break;
|
|
848
|
+
case "cycleDisplay":
|
|
849
|
+
c.cycleDisplay();
|
|
850
|
+
break;
|
|
851
|
+
case "setTempo":
|
|
852
|
+
c.setTempo(intent.bpm);
|
|
853
|
+
break;
|
|
854
|
+
case "setIn":
|
|
855
|
+
c.setInPoint();
|
|
856
|
+
break;
|
|
857
|
+
case "setOut":
|
|
858
|
+
c.setOutPoint();
|
|
859
|
+
break;
|
|
860
|
+
case "scrub": {
|
|
861
|
+
const tick = c.fractionToTick(intent.fraction);
|
|
862
|
+
if (intent.phase === "begin") c.beginScrub(tick);
|
|
863
|
+
else if (intent.phase === "move") c.updateScrub(tick);
|
|
864
|
+
else if (intent.phase === "end") c.endScrub();
|
|
865
|
+
else c.cancelScrub();
|
|
866
|
+
break;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
var transportViewManifest = {
|
|
871
|
+
id: transportManifest.id,
|
|
872
|
+
version: "1.0.0",
|
|
873
|
+
title: "Transport",
|
|
874
|
+
category: "time",
|
|
875
|
+
layout: { slot: "bottom" },
|
|
876
|
+
inputs: [{ id: "view", type: "object", label: "View state", description: "The TransportViewState the runtime derives from the controller on every draw." }],
|
|
877
|
+
outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, bpm?, fraction?, phase? } \u2014 applied by the runtime to the controller." }],
|
|
878
|
+
commands: []
|
|
879
|
+
};
|
|
880
|
+
function transportPanelView(state) {
|
|
881
|
+
return {
|
|
882
|
+
...state,
|
|
883
|
+
stopped: !state.playing,
|
|
884
|
+
playLabel: state.playing ? "Pause (Space)" : "Play (Space)",
|
|
885
|
+
positionLabel: `Position ${state.readout}`
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
var EMPTY = {
|
|
889
|
+
playing: false,
|
|
890
|
+
recording: false,
|
|
891
|
+
loopEnabled: false,
|
|
892
|
+
metronome: false,
|
|
893
|
+
punch: false,
|
|
894
|
+
bpm: 120,
|
|
895
|
+
show: { shuttle: false, record: false, loop: false, metronome: false, punch: false, bpm: false, inOut: false, scrubber: true },
|
|
896
|
+
readout: "",
|
|
897
|
+
displayLabel: "",
|
|
898
|
+
durationReadout: "",
|
|
899
|
+
progress: 0,
|
|
900
|
+
duration: 0,
|
|
901
|
+
currentTick: 0
|
|
902
|
+
};
|
|
903
|
+
var BEHAVIOURS = {
|
|
904
|
+
"time/transportPanelView": (inputs) => transportPanelView(inputs.view ?? EMPTY)
|
|
905
|
+
};
|
|
906
|
+
var ui = (kind) => ({ emit: "ui", value: { object: { kind: { value: kind } } } });
|
|
907
|
+
var text = (b) => ({ component: "text", props: { text: b } });
|
|
908
|
+
var button = (icon, label, kind, extra = {}) => ({
|
|
909
|
+
component: "chrome/IconButton",
|
|
910
|
+
...extra.when ? { when: extra.when } : {},
|
|
911
|
+
props: { size: { value: "sm" }, icon: { node: { component: `transport/${icon}` } }, label, ...extra.props ?? {} },
|
|
912
|
+
on: { onClick: ui(kind) }
|
|
913
|
+
});
|
|
914
|
+
var TRANSPORT_DECLARATION = {
|
|
915
|
+
format: "xeno.block@1",
|
|
916
|
+
manifest: transportViewManifest,
|
|
917
|
+
behaviour: "time/transportPanelView",
|
|
918
|
+
composition: {
|
|
919
|
+
component: "chrome/Column",
|
|
920
|
+
props: { className: { value: "xeno-transport-panel" }, tabIndex: { value: 0 }, role: { value: "group" }, "aria-label": { value: "Transport" } },
|
|
921
|
+
children: [
|
|
922
|
+
{
|
|
923
|
+
component: "chrome/Stack",
|
|
924
|
+
props: { direction: { value: "row" }, gap: { value: 3 }, pad: { value: "gutter" } },
|
|
925
|
+
children: [
|
|
926
|
+
button("StartIcon", { value: "Go to start" }, "goToStart"),
|
|
927
|
+
button("StepBackIcon", { value: "Step back" }, "stepBack"),
|
|
928
|
+
button("ShuttleLeftIcon", { value: "Shuttle reverse (J)" }, "shuttleBack", { when: { input: "view.show.shuttle" } }),
|
|
929
|
+
{
|
|
930
|
+
component: "chrome/IconButton",
|
|
931
|
+
props: {
|
|
932
|
+
size: { value: "sm" },
|
|
933
|
+
variant: { value: "primary" },
|
|
934
|
+
icon: { node: { component: "transport/PlayPauseIcon", props: { playing: { input: "view.playing" } } } },
|
|
935
|
+
label: { input: "view.playLabel" },
|
|
936
|
+
active: { input: "view.playing" }
|
|
937
|
+
},
|
|
938
|
+
on: { onClick: ui("togglePlay") }
|
|
939
|
+
},
|
|
940
|
+
button("StopIcon", { value: "Stop" }, "stop"),
|
|
941
|
+
button("ShuttleRightIcon", { value: "Shuttle forward (L)" }, "shuttleForward", { when: { input: "view.show.shuttle" } }),
|
|
942
|
+
button("StepForwardIcon", { value: "Step forward" }, "stepForward"),
|
|
943
|
+
button("EndIcon", { value: "Go to end" }, "goToEnd"),
|
|
944
|
+
button("RecordIcon", { value: "Record" }, "record", { when: { input: "view.show.record" }, props: { variant: { value: "danger" }, active: { input: "view.recording" } } }),
|
|
945
|
+
button("LoopIcon", { value: "Loop" }, "toggleLoop", { when: { input: "view.show.loop" }, props: { active: { input: "view.loopEnabled" } } }),
|
|
946
|
+
button("MetronomeIcon", { value: "Metronome" }, "toggleMetronome", { when: { input: "view.show.metronome" }, props: { active: { input: "view.metronome" } } }),
|
|
947
|
+
{ component: "chrome/TextButton", when: { input: "view.show.punch" }, props: { strong: { input: "view.punch" } }, children: [text({ value: "PUNCH" })] },
|
|
948
|
+
{
|
|
949
|
+
component: "chrome/Readout",
|
|
950
|
+
props: { value: { input: "view.readout" }, unit: { input: "view.displayLabel" }, label: { input: "view.positionLabel" }, title: { value: "Click to change time display" } },
|
|
951
|
+
on: { onClick: ui("cycleDisplay") }
|
|
952
|
+
},
|
|
953
|
+
{ component: "chrome/Readout", props: { size: { value: "sm" }, value: { input: "view.durationReadout" } } },
|
|
954
|
+
{
|
|
955
|
+
component: "chrome/NumberInput",
|
|
956
|
+
when: { input: "view.show.bpm" },
|
|
957
|
+
props: { caption: { value: "BPM" }, label: { value: "Tempo" }, value: { input: "view.bpm" } },
|
|
958
|
+
on: { onChange: { emit: "ui", value: { object: { kind: { value: "setTempo" }, bpm: { arg: "" } } } } }
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
component: "chrome/Stack",
|
|
962
|
+
when: { input: "view.show.inOut" },
|
|
963
|
+
props: { direction: { value: "row" }, gap: { value: 2 }, pad: { value: "none" } },
|
|
964
|
+
children: [
|
|
965
|
+
{ component: "chrome/TextButton", on: { onClick: ui("setIn") }, children: [text({ value: "IN" })] },
|
|
966
|
+
{ component: "chrome/TextButton", on: { onClick: ui("setOut") }, children: [text({ value: "OUT" })] }
|
|
967
|
+
]
|
|
968
|
+
}
|
|
969
|
+
]
|
|
970
|
+
},
|
|
971
|
+
{
|
|
972
|
+
component: "chrome/Slider",
|
|
973
|
+
when: { input: "view.show.scrubber" },
|
|
974
|
+
props: {
|
|
975
|
+
progress: { input: "view.progress" },
|
|
976
|
+
label: { value: "Playhead" },
|
|
977
|
+
valueMin: { value: 0 },
|
|
978
|
+
valueMax: { input: "view.duration" },
|
|
979
|
+
valueNow: { input: "view.currentTick" },
|
|
980
|
+
valueText: { input: "view.readout" }
|
|
981
|
+
},
|
|
982
|
+
on: { onScrub: { emit: "ui", value: { object: { kind: { value: "scrub" }, fraction: { arg: "" }, phase: { arg: "", index: 1 } } } } }
|
|
983
|
+
}
|
|
984
|
+
]
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
|
|
785
988
|
// src/time/transport/react/icons.tsx
|
|
786
989
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
787
990
|
var base = (size) => ({
|
|
@@ -854,6 +1057,24 @@ function MetronomeIcon({ size = 11 }) {
|
|
|
854
1057
|
/* @__PURE__ */ jsx("path", { d: "m12 18 4-11" })
|
|
855
1058
|
] });
|
|
856
1059
|
}
|
|
1060
|
+
function PlayPauseIcon({ playing, size }) {
|
|
1061
|
+
return playing ? /* @__PURE__ */ jsx(PauseIcon, { size }) : /* @__PURE__ */ jsx(PlayIcon, { size });
|
|
1062
|
+
}
|
|
1063
|
+
var TRANSPORT_ICONS = {
|
|
1064
|
+
"transport/PlayIcon": PlayIcon,
|
|
1065
|
+
"transport/PauseIcon": PauseIcon,
|
|
1066
|
+
"transport/PlayPauseIcon": PlayPauseIcon,
|
|
1067
|
+
"transport/StopIcon": StopIcon,
|
|
1068
|
+
"transport/RecordIcon": RecordIcon,
|
|
1069
|
+
"transport/StartIcon": StartIcon,
|
|
1070
|
+
"transport/EndIcon": EndIcon,
|
|
1071
|
+
"transport/StepBackIcon": StepBackIcon,
|
|
1072
|
+
"transport/StepForwardIcon": StepForwardIcon,
|
|
1073
|
+
"transport/ShuttleLeftIcon": ShuttleLeftIcon,
|
|
1074
|
+
"transport/ShuttleRightIcon": ShuttleRightIcon,
|
|
1075
|
+
"transport/LoopIcon": LoopIcon,
|
|
1076
|
+
"transport/MetronomeIcon": MetronomeIcon
|
|
1077
|
+
};
|
|
857
1078
|
|
|
858
1079
|
// src/time/transport/react/TransportPanelView.tsx
|
|
859
1080
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -879,40 +1100,8 @@ function TransportPanelView({ controller }) {
|
|
|
879
1100
|
rafRef.current = null;
|
|
880
1101
|
};
|
|
881
1102
|
}, [controller, animating]);
|
|
882
|
-
const
|
|
883
|
-
const
|
|
884
|
-
const tickFromPointer = useCallback(
|
|
885
|
-
(clientX) => {
|
|
886
|
-
const el = scrubRef.current;
|
|
887
|
-
if (!el) return 0;
|
|
888
|
-
const rect = el.getBoundingClientRect();
|
|
889
|
-
return controller.fractionToTick(rect.width > 0 ? (clientX - rect.left) / rect.width : 0);
|
|
890
|
-
},
|
|
891
|
-
[controller]
|
|
892
|
-
);
|
|
893
|
-
const onScrubDown = useCallback(
|
|
894
|
-
(e) => {
|
|
895
|
-
e.currentTarget.setPointerCapture(e.pointerId);
|
|
896
|
-
controller.beginScrub(tickFromPointer(e.clientX));
|
|
897
|
-
},
|
|
898
|
-
[controller, tickFromPointer]
|
|
899
|
-
);
|
|
900
|
-
const onScrubMove = useCallback(
|
|
901
|
-
(e) => {
|
|
902
|
-
if (controller.isScrubbing()) controller.updateScrub(tickFromPointer(e.clientX));
|
|
903
|
-
},
|
|
904
|
-
[controller, tickFromPointer]
|
|
905
|
-
);
|
|
906
|
-
const onScrubUp = useCallback(
|
|
907
|
-
(e) => {
|
|
908
|
-
try {
|
|
909
|
-
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
910
|
-
} catch {
|
|
911
|
-
}
|
|
912
|
-
controller.endScrub();
|
|
913
|
-
},
|
|
914
|
-
[controller]
|
|
915
|
-
);
|
|
1103
|
+
const view = transportPanelView(transportViewState(controller));
|
|
1104
|
+
const scrub = useCallback((fraction, phase) => applyTransportUi(controller, { kind: "scrub", fraction, phase }), [controller]);
|
|
916
1105
|
const onKeyDown = useCallback(
|
|
917
1106
|
(e) => {
|
|
918
1107
|
if (controller.handleKey({ key: e.key, ctrl: e.ctrlKey, meta: e.metaKey, shift: e.shiftKey }, "down")) {
|
|
@@ -941,59 +1130,25 @@ function TransportPanelView({ controller }) {
|
|
|
941
1130
|
/* @__PURE__ */ jsxs2(Stack, { direction: "row", gap: 3, pad: "gutter", children: [
|
|
942
1131
|
/* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(StartIcon, {}), label: "Go to start", onClick: () => controller.goToStart() }),
|
|
943
1132
|
/* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(StepBackIcon, {}), label: "Step back", onClick: () => controller.step(-1) }),
|
|
944
|
-
|
|
945
|
-
/* @__PURE__ */ jsx2(
|
|
946
|
-
IconButton,
|
|
947
|
-
{
|
|
948
|
-
size: "sm",
|
|
949
|
-
variant: "primary",
|
|
950
|
-
icon: playing ? /* @__PURE__ */ jsx2(PauseIcon, {}) : /* @__PURE__ */ jsx2(PlayIcon, {}),
|
|
951
|
-
label: playing ? "Pause (Space)" : "Play (Space)",
|
|
952
|
-
active: playing,
|
|
953
|
-
onClick: () => controller.togglePlay()
|
|
954
|
-
}
|
|
955
|
-
),
|
|
1133
|
+
view.show.shuttle && /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(ShuttleLeftIcon, {}), label: "Shuttle reverse (J)", onClick: () => controller.shuttleStep(-1) }),
|
|
1134
|
+
/* @__PURE__ */ jsx2(IconButton, { size: "sm", variant: "primary", icon: /* @__PURE__ */ jsx2(PlayPauseIcon, { playing: view.playing }), label: view.playLabel, active: view.playing, onClick: () => controller.togglePlay() }),
|
|
956
1135
|
/* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(StopIcon, {}), label: "Stop", onClick: () => controller.stop() }),
|
|
957
|
-
|
|
1136
|
+
view.show.shuttle && /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(ShuttleRightIcon, {}), label: "Shuttle forward (L)", onClick: () => controller.shuttleStep(1) }),
|
|
958
1137
|
/* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(StepForwardIcon, {}), label: "Step forward", onClick: () => controller.step(1) }),
|
|
959
1138
|
/* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(EndIcon, {}), label: "Go to end", onClick: () => controller.goToEnd() }),
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
/* @__PURE__ */ jsx2(
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
unit: (0, format_exports.displayLabel)(controller.getDisplay()),
|
|
969
|
-
label: `Position ${controller.getReadout()}`,
|
|
970
|
-
title: "Click to change time display",
|
|
971
|
-
onClick: () => controller.cycleDisplay()
|
|
972
|
-
}
|
|
973
|
-
),
|
|
974
|
-
/* @__PURE__ */ jsx2(Readout, { size: "sm", value: controller.getDurationReadout() }),
|
|
975
|
-
controller.showsControl("bpm") && /* @__PURE__ */ jsx2(NumberInput, { caption: "BPM", label: "Tempo", value: state.bpm ?? 120, onChange: (bpm) => controller.setTempo(bpm) }),
|
|
976
|
-
controller.showsControl("inOut") && /* @__PURE__ */ jsxs2(Stack, { direction: "row", gap: 2, pad: "none", children: [
|
|
1139
|
+
view.show.record && /* @__PURE__ */ jsx2(IconButton, { size: "sm", variant: "danger", icon: /* @__PURE__ */ jsx2(RecordIcon, {}), label: "Record", active: view.recording, onClick: () => controller.record() }),
|
|
1140
|
+
view.show.loop && /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(LoopIcon, {}), label: "Loop", active: view.loopEnabled, onClick: () => controller.toggleLoop() }),
|
|
1141
|
+
view.show.metronome && /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(MetronomeIcon, {}), label: "Metronome", active: view.metronome, onClick: () => controller.toggleMetronome() }),
|
|
1142
|
+
view.show.punch && /* @__PURE__ */ jsx2(TextButton, { strong: view.punch, children: "PUNCH" }),
|
|
1143
|
+
/* @__PURE__ */ jsx2(Readout, { value: view.readout, unit: view.displayLabel, label: view.positionLabel, title: "Click to change time display", onClick: () => controller.cycleDisplay() }),
|
|
1144
|
+
/* @__PURE__ */ jsx2(Readout, { size: "sm", value: view.durationReadout }),
|
|
1145
|
+
view.show.bpm && /* @__PURE__ */ jsx2(NumberInput, { caption: "BPM", label: "Tempo", value: view.bpm, onChange: (bpm) => controller.setTempo(bpm) }),
|
|
1146
|
+
view.show.inOut && /* @__PURE__ */ jsxs2(Stack, { direction: "row", gap: 2, pad: "none", children: [
|
|
977
1147
|
/* @__PURE__ */ jsx2(TextButton, { onClick: () => controller.setInPoint(), children: "IN" }),
|
|
978
1148
|
/* @__PURE__ */ jsx2(TextButton, { onClick: () => controller.setOutPoint(), children: "OUT" })
|
|
979
1149
|
] })
|
|
980
1150
|
] }),
|
|
981
|
-
|
|
982
|
-
Slider,
|
|
983
|
-
{
|
|
984
|
-
trackRef: scrubRef,
|
|
985
|
-
progress: controller.getProgress(),
|
|
986
|
-
label: "Playhead",
|
|
987
|
-
valueMin: 0,
|
|
988
|
-
valueMax: controller.getDuration(),
|
|
989
|
-
valueNow: controller.getCurrentTick(),
|
|
990
|
-
valueText: controller.getReadout(),
|
|
991
|
-
onPointerDown: onScrubDown,
|
|
992
|
-
onPointerMove: onScrubMove,
|
|
993
|
-
onPointerUp: onScrubUp,
|
|
994
|
-
onPointerCancel: () => controller.cancelScrub()
|
|
995
|
-
}
|
|
996
|
-
)
|
|
1151
|
+
view.show.scrubber && /* @__PURE__ */ jsx2(Slider, { progress: view.progress, label: "Playhead", valueMin: 0, valueMax: view.duration, valueNow: view.currentTick, valueText: view.readout, onScrub: scrub })
|
|
997
1152
|
]
|
|
998
1153
|
}
|
|
999
1154
|
);
|
|
@@ -1004,11 +1159,20 @@ function createTransportPanel(options = {}) {
|
|
|
1004
1159
|
return {
|
|
1005
1160
|
manifest: transportManifest,
|
|
1006
1161
|
activate(host) {
|
|
1007
|
-
const
|
|
1162
|
+
const { render: customRender, ...controllerOptions } = options;
|
|
1163
|
+
const controller = new TransportPanelController(host, controllerOptions);
|
|
1008
1164
|
void controller.load();
|
|
1009
1165
|
let root = null;
|
|
1166
|
+
let unrender = null;
|
|
1010
1167
|
return {
|
|
1011
1168
|
render(el) {
|
|
1169
|
+
if (customRender) {
|
|
1170
|
+
unrender = customRender(el, controller);
|
|
1171
|
+
return () => {
|
|
1172
|
+
unrender?.();
|
|
1173
|
+
unrender = null;
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1012
1176
|
root = createRoot(el);
|
|
1013
1177
|
root.render(createElement(TransportPanelView, { controller }));
|
|
1014
1178
|
return () => {
|
|
@@ -1031,6 +1195,8 @@ function createTransportPanel(options = {}) {
|
|
|
1031
1195
|
dispose() {
|
|
1032
1196
|
root?.unmount();
|
|
1033
1197
|
root = null;
|
|
1198
|
+
unrender?.();
|
|
1199
|
+
unrender = null;
|
|
1034
1200
|
controller.dispose();
|
|
1035
1201
|
}
|
|
1036
1202
|
};
|
|
@@ -3338,10 +3504,10 @@ function gridStart(monthKey, firstDayOfWeek) {
|
|
|
3338
3504
|
return addDays(first, -offset);
|
|
3339
3505
|
}
|
|
3340
3506
|
function statusTone(value) {
|
|
3341
|
-
const
|
|
3342
|
-
if (/done|complete|published|paid|ok/.test(
|
|
3343
|
-
if (/pending|draft|scheduled|review/.test(
|
|
3344
|
-
if (/fail|error|cancel|reject|overdue/.test(
|
|
3507
|
+
const text2 = String(value ?? "").toLowerCase();
|
|
3508
|
+
if (/done|complete|published|paid|ok/.test(text2)) return "success";
|
|
3509
|
+
if (/pending|draft|scheduled|review/.test(text2)) return "warning";
|
|
3510
|
+
if (/fail|error|cancel|reject|overdue/.test(text2)) return "error";
|
|
3345
3511
|
return "neutral";
|
|
3346
3512
|
}
|
|
3347
3513
|
function columnMap(result) {
|
|
@@ -4403,6 +4569,9 @@ export {
|
|
|
4403
4569
|
MIN_MAJOR_PX,
|
|
4404
4570
|
MIN_MINOR_PX,
|
|
4405
4571
|
TIMELINE_PANEL_ID,
|
|
4572
|
+
BEHAVIOURS as TRANSPORT_BEHAVIOURS,
|
|
4573
|
+
TRANSPORT_DECLARATION,
|
|
4574
|
+
TRANSPORT_ICONS,
|
|
4406
4575
|
TRIM_SNAP_PX,
|
|
4407
4576
|
TimelineController,
|
|
4408
4577
|
TimelinePanelView,
|
|
@@ -4413,6 +4582,7 @@ export {
|
|
|
4413
4582
|
addDays,
|
|
4414
4583
|
addMonths,
|
|
4415
4584
|
alignToTileGrid,
|
|
4585
|
+
applyTransportUi,
|
|
4416
4586
|
beginDrag,
|
|
4417
4587
|
blitTile,
|
|
4418
4588
|
buildCells,
|
|
@@ -4483,6 +4653,9 @@ export {
|
|
|
4483
4653
|
todayKey,
|
|
4484
4654
|
transportManifest,
|
|
4485
4655
|
transportPanel,
|
|
4656
|
+
transportPanelView,
|
|
4657
|
+
transportViewManifest,
|
|
4658
|
+
transportViewState,
|
|
4486
4659
|
trimModeFor,
|
|
4487
4660
|
visibleClips,
|
|
4488
4661
|
visibleRows,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenosystem/blocks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "XENO Blocks — rung 3 of the front ladder: components composed into a contract-bearing unit (manifest: ports, intents, commands, agent surface), rendered by @xenosystem/workbench. ONE package, one subpath per family (/auth, /edit, /data, /time, /ops, /trust, /agent), one named export per block — XENO PACKAGE NAMING - STANDARD.md.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@duckdb/duckdb-wasm": ">=1.28.0",
|
|
62
|
-
"@xenosystem/block-sdk": "
|
|
63
|
-
"@xenosystem/components": ">=0.
|
|
62
|
+
"@xenosystem/block-sdk": ">=0.3.2 <1",
|
|
63
|
+
"@xenosystem/components": ">=0.16.0 <1",
|
|
64
64
|
"@xenosystem/data-core": "^0.1.0",
|
|
65
65
|
"@xenosystem/elements-react": ">=0.0.1",
|
|
66
66
|
"@xenosystem/time-core": "^0.1.0",
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
"@types/node": "^22.0.0",
|
|
76
76
|
"@types/react": "^19.0.0",
|
|
77
77
|
"@types/react-dom": "^19.0.0",
|
|
78
|
-
"@xenosystem/block-sdk": "^0.3.
|
|
79
|
-
"@xenosystem/components": "^0.
|
|
78
|
+
"@xenosystem/block-sdk": "^0.3.2",
|
|
79
|
+
"@xenosystem/components": "^0.16.0",
|
|
80
80
|
"@xenosystem/data-core": "^0.1.0",
|
|
81
81
|
"@xenosystem/elements-react": "0.0.1",
|
|
82
82
|
"@xenosystem/time-core": "^0.1.0",
|