libpetri 1.7.0 → 1.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/debug/index.d.ts +76 -19
- package/dist/debug/index.js +53 -8
- package/dist/debug/index.js.map +1 -1
- package/dist/doclet/index.d.ts +1 -1
- package/dist/{event-store-DePCZb33.d.ts → event-store-BnyHh3TF.d.ts} +1 -1
- package/dist/export/index.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js.map +1 -1
- package/dist/{petri-net-DrTpTRNy.d.ts → petri-net-D-GN9g_D.d.ts} +9 -0
- package/dist/verification/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/debug/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Writable } from 'node:stream';
|
|
2
|
-
import { a as PetriNet, b as Transition, T as Token } from '../petri-net-
|
|
3
|
-
import { E as EventStore, N as NetEvent } from '../event-store-
|
|
2
|
+
import { a as PetriNet, b as Transition, T as Token } from '../petri-net-D-GN9g_D.js';
|
|
3
|
+
import { E as EventStore, N as NetEvent } from '../event-store-BnyHh3TF.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Commands sent from debug UI client to server via WebSocket.
|
|
@@ -106,7 +106,19 @@ interface SessionSummary {
|
|
|
106
106
|
interface TokenInfo {
|
|
107
107
|
readonly id: string | null;
|
|
108
108
|
readonly type: string;
|
|
109
|
+
/**
|
|
110
|
+
* `String(value)` form — stable display field that the bundled debug UI relies on.
|
|
111
|
+
* Always populated unless compact mode strips values.
|
|
112
|
+
*/
|
|
109
113
|
readonly value: string | null;
|
|
114
|
+
/**
|
|
115
|
+
* Structured JSON representation of the token value when the value is a plain
|
|
116
|
+
* JSON-friendly object / enum-like string / primitive. Populated alongside `value`
|
|
117
|
+
* (not instead of) so LLM-facing consumers can project typed fields without parsing
|
|
118
|
+
* the stringified form. Omitted from the wire when absent.
|
|
119
|
+
* (libpetri 1.8.0+)
|
|
120
|
+
*/
|
|
121
|
+
readonly structured?: unknown;
|
|
110
122
|
readonly timestamp: string | null;
|
|
111
123
|
}
|
|
112
124
|
interface NetEventInfo {
|
|
@@ -487,7 +499,23 @@ declare class MarkingCache {
|
|
|
487
499
|
|
|
488
500
|
/** Converts a NetEvent to a serializable NetEventInfo. */
|
|
489
501
|
declare function toEventInfo(event: NetEvent, compact?: boolean): NetEventInfo;
|
|
490
|
-
/**
|
|
502
|
+
/**
|
|
503
|
+
* Converts a Token to a serializable {@link TokenInfo}.
|
|
504
|
+
*
|
|
505
|
+
* @remarks
|
|
506
|
+
* The emitted `type` is `value.constructor.name` for objects and `typeof value`
|
|
507
|
+
* for primitives — a *simple name*, not a fully-qualified type identifier.
|
|
508
|
+
* TypeScript has no portable FQN, so cross-language replay from TypeScript
|
|
509
|
+
* archives into a Java reader loses the original type identity (Java's
|
|
510
|
+
* `Class.forName` will fail on simple names) and falls through to the
|
|
511
|
+
* `Token<JsonNode>` graceful-degradation path. The `structured` payload
|
|
512
|
+
* survives intact across languages.
|
|
513
|
+
*
|
|
514
|
+
* The v3 archive body format described in [EVT-025](../../../spec/08-events-observability.md)
|
|
515
|
+
* always emits `structured` alongside `value` so the bundled debug UI keeps
|
|
516
|
+
* rendering while LLM-facing consumers get typed fields. See {@link structuredValue}
|
|
517
|
+
* for the projection rules.
|
|
518
|
+
*/
|
|
491
519
|
declare function tokenInfo(token: Token<unknown>): TokenInfo;
|
|
492
520
|
/** Converts a Token to compact TokenInfo (type only, no value). */
|
|
493
521
|
declare function compactTokenInfo(token: Token<unknown>): TokenInfo;
|
|
@@ -529,14 +557,17 @@ declare class DebugAwareEventStore implements EventStore {
|
|
|
529
557
|
*
|
|
530
558
|
* - **v1** (libpetri 1.5.x–1.6.x): original format. Header carries `sessionId`,
|
|
531
559
|
* `netName`, `dotDiagram`, `startTime`, `eventCount`, and net `structure`.
|
|
532
|
-
* - **v2** (libpetri 1.7.
|
|
533
|
-
* {@link SessionMetadata}
|
|
534
|
-
*
|
|
535
|
-
*
|
|
560
|
+
* - **v2** (libpetri 1.7.x): adds `endTime`, user-defined `tags`, and pre-computed
|
|
561
|
+
* {@link SessionMetadata}. Events inside v2 archives use the legacy `toString`-based
|
|
562
|
+
* token format — types are erased on disk.
|
|
563
|
+
* - **v3** (libpetri 1.8.0+): same header shape as v2. Differs in the event body —
|
|
564
|
+
* token values are serialized with a `structured` JSON payload in addition to the
|
|
565
|
+
* legacy `value` string, so consumers that understand the original shape can
|
|
566
|
+
* surface typed fields without parsing the `toString` form.
|
|
536
567
|
*
|
|
537
568
|
* The {@link SessionArchiveReader} peeks the `version` field via a lenient JSON
|
|
538
|
-
* parse and dispatches to the correct concrete type.
|
|
539
|
-
*
|
|
569
|
+
* parse and dispatches to the correct concrete type. All three versions coexist
|
|
570
|
+
* in the same storage bucket.
|
|
540
571
|
*/
|
|
541
572
|
|
|
542
573
|
/** Common fields shared by v1 and v2 archive headers. */
|
|
@@ -567,19 +598,30 @@ interface SessionArchiveV2 extends SessionArchiveBase {
|
|
|
567
598
|
/** Pre-computed aggregate stats. Always present; `emptyMetadata()` for no-event sessions. */
|
|
568
599
|
readonly metadata: SessionMetadata;
|
|
569
600
|
}
|
|
601
|
+
/**
|
|
602
|
+
* v3 archive header (libpetri 1.8.0+). Structurally identical to `SessionArchiveV2`;
|
|
603
|
+
* the version bump signals that the event body carries `structured` token payloads
|
|
604
|
+
* alongside the legacy `value` string.
|
|
605
|
+
*/
|
|
606
|
+
interface SessionArchiveV3 extends SessionArchiveBase {
|
|
607
|
+
readonly version: 3;
|
|
608
|
+
readonly endTime?: string;
|
|
609
|
+
readonly tags: Readonly<Record<string, string>>;
|
|
610
|
+
readonly metadata: SessionMetadata;
|
|
611
|
+
}
|
|
570
612
|
/**
|
|
571
613
|
* Discriminated union of all supported archive header versions.
|
|
572
614
|
*
|
|
573
615
|
* Type-narrowing example:
|
|
574
616
|
* ```ts
|
|
575
|
-
* if (archive.version
|
|
576
|
-
* // TS knows archive
|
|
617
|
+
* if (archive.version >= 2) {
|
|
618
|
+
* // TS knows archive has tags / endTime / metadata here.
|
|
577
619
|
* }
|
|
578
620
|
* ```
|
|
579
621
|
*/
|
|
580
|
-
type SessionArchive = SessionArchiveV1 | SessionArchiveV2;
|
|
622
|
+
type SessionArchive = SessionArchiveV1 | SessionArchiveV2 | SessionArchiveV3;
|
|
581
623
|
/** Version written by default by {@link SessionArchiveWriter.write} (latest supported). */
|
|
582
|
-
declare const CURRENT_VERSION =
|
|
624
|
+
declare const CURRENT_VERSION = 3;
|
|
583
625
|
/**
|
|
584
626
|
* Pre-computed aggregate statistics attached to a v2 session archive header.
|
|
585
627
|
*
|
|
@@ -636,17 +678,26 @@ declare class FileSessionArchiveStorage implements SessionArchiveStorage {
|
|
|
636
678
|
*
|
|
637
679
|
* ## Format selection
|
|
638
680
|
*
|
|
639
|
-
* `write()` defaults to {@link CURRENT_VERSION} (
|
|
681
|
+
* `write()` defaults to {@link CURRENT_VERSION} (v3 as of libpetri 1.8.0).
|
|
640
682
|
* Callers that need to emit legacy archives — compatibility tests or readers
|
|
641
|
-
* pinned to libpetri
|
|
642
|
-
*
|
|
643
|
-
*
|
|
644
|
-
*
|
|
683
|
+
* pinned to older libpetri versions — can call `writeV1()` or `writeV2()`.
|
|
684
|
+
*
|
|
685
|
+
* Note: all writers now emit the v3 token body format (structured alongside
|
|
686
|
+
* value-string) regardless of header version. A 1.8.0+ writer cannot produce
|
|
687
|
+
* byte-for-byte 1.7.x event bodies.
|
|
688
|
+
*
|
|
689
|
+
* Cross-language note: the `type` field in each serialized `TokenInfo` is
|
|
690
|
+
* `value.constructor.name` — a simple name, not an FQN. Replaying a TypeScript
|
|
691
|
+
* archive through the Java reader therefore cannot reconstruct the original
|
|
692
|
+
* typed token (Java needs an FQN to `Class.forName`); Java falls through to
|
|
693
|
+
* `Token<JsonNode>` preserving the `structured` JSON payload. See
|
|
694
|
+
* {@link tokenInfo} for the full asymmetry and the [EVT-025](../../../../spec/08-events-observability.md)
|
|
695
|
+
* spec entry for the full wire-format contract.
|
|
645
696
|
*/
|
|
646
697
|
|
|
647
698
|
declare class SessionArchiveWriter {
|
|
648
699
|
/**
|
|
649
|
-
* Writes a complete session archive in the current format (
|
|
700
|
+
* Writes a complete session archive in the current format (v3 as of 1.8.0)
|
|
650
701
|
* and returns the compressed bytes.
|
|
651
702
|
*/
|
|
652
703
|
write(session: DebugSession): Buffer;
|
|
@@ -665,6 +716,12 @@ declare class SessionArchiveWriter {
|
|
|
665
716
|
* passes walk the same sequence from the start.
|
|
666
717
|
*/
|
|
667
718
|
writeV2(session: DebugSession): Buffer;
|
|
719
|
+
/**
|
|
720
|
+
* Writes a session in the v3 format — same header shape as v2, with version=3
|
|
721
|
+
* signalling that token payloads carry a `structured` field alongside the
|
|
722
|
+
* legacy `value` string (see {@link tokenInfo}).
|
|
723
|
+
*/
|
|
724
|
+
writeV3(session: DebugSession): Buffer;
|
|
668
725
|
/**
|
|
669
726
|
* Shared framing logic: length-prefixed header JSON, then length-prefixed
|
|
670
727
|
* event JSON, then gzip. Both v1 and v2 archives use the identical event
|
package/dist/debug/index.js
CHANGED
|
@@ -118,7 +118,7 @@ var DebugEventStore = class {
|
|
|
118
118
|
};
|
|
119
119
|
|
|
120
120
|
// src/debug/archive/session-archive.ts
|
|
121
|
-
var CURRENT_VERSION =
|
|
121
|
+
var CURRENT_VERSION = 3;
|
|
122
122
|
var MIN_SUPPORTED_VERSION = 1;
|
|
123
123
|
function emptyMetadata() {
|
|
124
124
|
return { eventTypeHistogram: {}, hasErrors: false };
|
|
@@ -174,6 +174,14 @@ function parseHeader(metaJson) {
|
|
|
174
174
|
metadata: v2.metadata ?? emptyMetadata()
|
|
175
175
|
};
|
|
176
176
|
}
|
|
177
|
+
case 3: {
|
|
178
|
+
const v3 = raw;
|
|
179
|
+
return {
|
|
180
|
+
...v3,
|
|
181
|
+
tags: v3.tags ?? {},
|
|
182
|
+
metadata: v3.metadata ?? emptyMetadata()
|
|
183
|
+
};
|
|
184
|
+
}
|
|
177
185
|
default:
|
|
178
186
|
throw new Error(
|
|
179
187
|
`Unsupported archive version: ${raw.version} (reader supports ${MIN_SUPPORTED_VERSION}..${CURRENT_VERSION})`
|
|
@@ -238,10 +246,8 @@ function eventInfoToNetEvent(info) {
|
|
|
238
246
|
}
|
|
239
247
|
}
|
|
240
248
|
function infoToToken(t) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
createdAt: t.timestamp ? new Date(t.timestamp).getTime() : Date.now()
|
|
244
|
-
};
|
|
249
|
+
const createdAt = t.timestamp ? new Date(t.timestamp).getTime() : Date.now();
|
|
250
|
+
return t.structured === void 0 ? { value: t.value, createdAt } : { value: t.value, createdAt, structured: t.structured };
|
|
245
251
|
}
|
|
246
252
|
|
|
247
253
|
// src/debug/place-analysis.ts
|
|
@@ -710,12 +716,30 @@ function tokenInfo(token) {
|
|
|
710
716
|
const value = token.value;
|
|
711
717
|
const type = value != null ? typeof value === "object" ? value.constructor.name : typeof value : "null";
|
|
712
718
|
const fullValue = value != null ? String(value) : "null";
|
|
713
|
-
|
|
719
|
+
const info = {
|
|
714
720
|
id: null,
|
|
715
721
|
type,
|
|
716
722
|
value: fullValue,
|
|
717
723
|
timestamp: new Date(token.createdAt).toISOString()
|
|
718
724
|
};
|
|
725
|
+
const structured = structuredValue(value);
|
|
726
|
+
return structured === void 0 ? info : { ...info, structured };
|
|
727
|
+
}
|
|
728
|
+
function structuredValue(value) {
|
|
729
|
+
if (value == null) return void 0;
|
|
730
|
+
const t = typeof value;
|
|
731
|
+
if (t === "string" || t === "number" || t === "boolean") return value;
|
|
732
|
+
if (t === "bigint") return String(value);
|
|
733
|
+
if (t === "symbol" || t === "function") return void 0;
|
|
734
|
+
try {
|
|
735
|
+
const cloned = JSON.parse(JSON.stringify(value));
|
|
736
|
+
if (cloned && typeof cloned === "object" && !Array.isArray(cloned) && Object.keys(cloned).length === 0) {
|
|
737
|
+
return void 0;
|
|
738
|
+
}
|
|
739
|
+
return cloned;
|
|
740
|
+
} catch {
|
|
741
|
+
return void 0;
|
|
742
|
+
}
|
|
719
743
|
}
|
|
720
744
|
function compactTokenInfo(token) {
|
|
721
745
|
const value = token.value;
|
|
@@ -1548,11 +1572,11 @@ function isErrorEvent(event) {
|
|
|
1548
1572
|
// src/debug/archive/session-archive-writer.ts
|
|
1549
1573
|
var SessionArchiveWriter = class {
|
|
1550
1574
|
/**
|
|
1551
|
-
* Writes a complete session archive in the current format (
|
|
1575
|
+
* Writes a complete session archive in the current format (v3 as of 1.8.0)
|
|
1552
1576
|
* and returns the compressed bytes.
|
|
1553
1577
|
*/
|
|
1554
1578
|
write(session) {
|
|
1555
|
-
return this.
|
|
1579
|
+
return this.writeV3(session);
|
|
1556
1580
|
}
|
|
1557
1581
|
/**
|
|
1558
1582
|
* Writes a session in the legacy v1 format. Use only for compatibility
|
|
@@ -1598,6 +1622,27 @@ var SessionArchiveWriter = class {
|
|
|
1598
1622
|
};
|
|
1599
1623
|
return this.writeFramed(header, session);
|
|
1600
1624
|
}
|
|
1625
|
+
/**
|
|
1626
|
+
* Writes a session in the v3 format — same header shape as v2, with version=3
|
|
1627
|
+
* signalling that token payloads carry a `structured` field alongside the
|
|
1628
|
+
* legacy `value` string (see {@link tokenInfo}).
|
|
1629
|
+
*/
|
|
1630
|
+
writeV3(session) {
|
|
1631
|
+
const metadata = computeMetadata(session.eventStore);
|
|
1632
|
+
const header = {
|
|
1633
|
+
version: 3,
|
|
1634
|
+
sessionId: session.sessionId,
|
|
1635
|
+
netName: session.netName,
|
|
1636
|
+
dotDiagram: session.dotDiagram,
|
|
1637
|
+
startTime: new Date(session.startTime).toISOString(),
|
|
1638
|
+
endTime: session.endTime !== void 0 ? new Date(session.endTime).toISOString() : void 0,
|
|
1639
|
+
eventCount: session.eventStore.eventCount(),
|
|
1640
|
+
tags: { ...session.tags },
|
|
1641
|
+
metadata,
|
|
1642
|
+
structure: buildNetStructure(session)
|
|
1643
|
+
};
|
|
1644
|
+
return this.writeFramed(header, session);
|
|
1645
|
+
}
|
|
1601
1646
|
/**
|
|
1602
1647
|
* Shared framing logic: length-prefixed header JSON, then length-prefixed
|
|
1603
1648
|
* event JSON, then gzip. Both v1 and v2 archives use the identical event
|