@onlyworlds/sdk 4.68.0 → 4.70.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/AGENTS.md CHANGED
@@ -94,6 +94,9 @@ against live data). The v1 surface (`OnlyWorldsClient`, the `ElementType` enum)
94
94
  first, UTF-8 name order, 1980 stamps) and holds only `world.json` and the folder's parts.
95
95
  Producers marked `"private": true` in `records/RECORDS.json` are left out whole unless
96
96
  `writeWorldFile(files, topDir, { includePrivateRecords: true })` (since 4.63.0; OW-8).
97
+ Element files marked `hidden: true` travel by default (a copy); a share passes
98
+ `{ includeHidden: false, report: r => r.hiddenLeftOut }` to leave them out whole and count
99
+ them (since 4.70.0; §4.8).
97
100
  - World calendars (since 4.20.0): `worldCalendars(elements)` finds the elements carrying
98
101
  `atlas_calendar` (Atlas owns the field: read it, never write it); `resolveCalendarLens` picks
99
102
  one; `formatStep(config, step)` names a point on the world's integer time line, `parseDate`
package/CHANGELOG.md CHANGED
@@ -5,6 +5,24 @@ earlier history lives in git log only.
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [4.70.0] - 2026-10-23
9
+
10
+ ### Added
11
+
12
+ - **`writeWorldFile(files, topDir, { includeHidden: false })`** (folder spec §4.8, Skeld, OW Atlas h20 #11469): a world file is a copy, so an element file carrying the hidden mark travels byte for byte by default, as before. A tool making a file to hand to someone else passes `includeHidden: false`, and every `.json` file directly in a type folder of `elements/` or the legacy `spatial/` whose JSON has a top-level `hidden` (anything but absent, `null` or `false`, so `"true"` and `1` count, as the Python package's `is_hidden`) is left out whole. A file there that is not UTF-8 JSON, or not an object, is kept. Nothing else is rewritten: a visible element's link to a hidden one keeps its id. The two defaults differ on purpose: private records out unless asked, hidden kept unless the write is a share.
13
+ - **`report: (r: OwWriteWorldFileReport) => void`**, a `writeWorldFile` option: called once with `{ hiddenLeftOut }` after the archive is made and before it is returned, never on a refusal. The return stays the bytes. An `includeHidden` that is not a boolean, or a `report` that is not a function, is a `TypeError` before anything is written; both keys join the options fence.
14
+
15
+ ### Fixed
16
+
17
+ - **`draught`'s doc comment names `compact`** (4.69.0, keel #585), so the docs' generated reference row carries it.
18
+ - Tests: a hidden element file byte-identical by default and with `includeHidden: true`, the report 0; left out as a share, the report 1, every other file byte-identical; the legacy layout, `.JSON`, and a doubtful mark left out; not JSON, not UTF-8, not an object, a null or nested mark, a deeper file, a non-JSON file and the other parts kept; the same bytes for the same files either way; the report not called on a refusal; the fence. Watched failing with the leave-out turned into a keep (3 tests red), restored. The 85-case `.owworld` set unchanged.
19
+
20
+ ## [4.69.0] - 2026-10-23
21
+
22
+ ### Added
23
+
24
+ - **`draught(id, { compact: true })`** (keel #585, PR 198): the draught without its empty sections. Every empty array or object section and an empty `cut` are left out. The frame (`world`, `calendar`, `as_of`, `now`, `mode`, `policy`) and every null stay, so a null is still an answer: `character` null means she is hidden from this reader, `style` null that she has no style element, `recent_cursor` null that the read had no `since`. An absent section means nothing in it, never that it was not read (`policy.components` says what was). The answer is typed `OwDraughtCompact` (`cut` optional); without `compact`, or with `compact: false`, it is `OwDraught` as before, the fixed shape. A `compact` that is not a boolean is a TypeError before anything is sent. MCP's `get_draught` defaults to compact; this route defaults to the fixed shape.
25
+
8
26
  ## [4.68.0] - 2026-10-23
9
27
 
10
28
  ### Fixed
package/README.md CHANGED
@@ -299,6 +299,15 @@ The writer gives the same bytes for the same files: the `mimetype` marker first,
299
299
 
300
300
  `records/` travels byte for byte, except a producer's directory that `records/RECORDS.json` marks `"private": true`: that one is left out whole, and `RECORDS.json` itself travels unchanged, so the reader can see a producer was left out. Pass `writeWorldFile(files, topDir, { includePrivateRecords: true })` to carry private records too. A `RECORDS.json` that is not a JSON array of objects is refused with a `TypeError` unless you pass that option, since the writer cannot tell which records are private.
301
301
 
302
+ An element file marked hidden (`"hidden": true` at the top of its JSON, spec §4.8) travels byte for byte by default: a world file is a copy, also of your own world. When the file is a share, made to hand to someone else, pass `includeHidden: false`: every hidden file under `elements/<type>/` (or the old `spatial/<type>/`) is left out whole, and `report` tells you how many. Nothing else changes: a visible element's link to a hidden one keeps its id. A file there that is not JSON is kept.
303
+
304
+ ```typescript
305
+ let left = 0;
306
+ const share = writeWorldFile(files, topDir, { includeHidden: false, report: r => { left = r.hiddenLeftOut; } });
307
+ ```
308
+
309
+ The two defaults differ on purpose: private records stay out unless you ask, hidden elements stay in unless the write is a share.
310
+
302
311
  ## World calendars
303
312
 
304
313
  A world's time is an integer line (`time_range_current` is a point on it, and so is an Event's `start_date`). A calendar names its points: months, days, eras. Atlas keeps a calendar on an element (a Construct by convention) in its `atlas_calendar` field, and the SDK reads it with Atlas's own calendar code (since 4.20.0). Atlas owns that field and is its only writer; read it, never write it.
package/dist/index.d.ts CHANGED
@@ -2748,6 +2748,15 @@ interface OwDraughtPolicy {
2748
2748
  budget?: number;
2749
2749
  /** The sheet's reach: 1 (default) what her own element links to, 0 none. */
2750
2750
  depth?: 0 | 1;
2751
+ /**
2752
+ * `true` (keel #585) leaves out every empty section (an empty array or object) and an empty `cut`;
2753
+ * the frame (`world`, `calendar`, `as_of`, `now`, `mode`, `policy`) and every null stay, so a null
2754
+ * is still an answer (`character`: she is hidden from this reader; `style`: she has no style
2755
+ * element; `recent_cursor`: this read had no `since`). An absent section means nothing in it, never
2756
+ * that it was not read (`policy.components` says what was read). Default `false`, the fixed shape;
2757
+ * with `compact` the answer is typed `OwDraughtCompact`.
2758
+ */
2759
+ compact?: boolean;
2751
2760
  }
2752
2761
  /**
2753
2762
  * A section of the draught, in the packet's order (keel's COMPONENTS). `messages`, `room` (keel #556:
@@ -2771,6 +2780,10 @@ interface OwDraughtItem {
2771
2780
  element: OwElement;
2772
2781
  }
2773
2782
  /** One Character's context in one read, GET /character/{id}/context (keel PR 155, D143; the draught). */
2783
+ /** The draught under `compact` (keel #585): every section may be absent, and so may `cut` (nothing was cut). */
2784
+ type OwDraughtCompact = Omit<OwDraught, 'cut'> & {
2785
+ cut?: Record<string, number>;
2786
+ };
2774
2787
  interface OwDraught {
2775
2788
  world: {
2776
2789
  id: string;
@@ -2862,8 +2875,8 @@ interface OwCreateAccountWorldInput {
2862
2875
  }
2863
2876
  /**
2864
2877
  * createAccountWorld's 201: the world's row as listAccountWorlds lists it, plus the full write key
2865
- * once in `key` (never shown again). keel's document gives this answer no schema; the keys are
2866
- * keel's handler's (`accounts/api.py`, `create_world`: the list row plus `key`).
2878
+ * once in `key` (never shown again). keel's document names it `AccountWorldCreated` (keel #579), and
2879
+ * Assembly's verify-sdk-wire holds this type to it key for key.
2867
2880
  */
2868
2881
  interface OwCreatedAccountWorld {
2869
2882
  id: string;
@@ -3631,9 +3644,14 @@ declare class OwV2Client {
3631
3644
  * Character they can see; a player seat or a guest for its own Character only (another id is
3632
3645
  * 404). `asOf` is a filter on the elements' own dates, not time travel. A `cut` that is not
3633
3646
  * empty means the serving is partial (`cut.proposed` also counts proposed elements left out because
3634
- * the component was not named). Served `Cache-Control: private, no-store`.
3647
+ * the component was not named). `compact: true` leaves out every empty section and an empty `cut`,
3648
+ * the frame and every null kept, answered as `OwDraughtCompact` (keel #585). Served
3649
+ * `Cache-Control: private, no-store`.
3635
3650
  */
3636
- draught(characterId: string, policy?: OwDraughtPolicy): Promise<OwDraught>;
3651
+ draught(characterId: string, policy?: OwDraughtPolicy & {
3652
+ compact?: false;
3653
+ }): Promise<OwDraught>;
3654
+ draught(characterId: string, policy: OwDraughtPolicy): Promise<OwDraughtCompact>;
3637
3655
  /** Cursor-walk every page of a type. Politeness: uses config pageSize. */
3638
3656
  listAll(type: ElementType | string, params?: Omit<ListParams, 'cursor'>): AsyncGenerator<OwElement>;
3639
3657
  /**
@@ -4534,7 +4552,8 @@ declare function typeWord(world: object | null | undefined, type: string, opts?:
4534
4552
  * 1980-01-01 00:00, in the UTF-8 byte order of its name, JSON deflated and
4535
4553
  * everything else stored. `records/` travels whole and byte-exact, except the
4536
4554
  * producers `records/RECORDS.json` marks private, left out whole unless the
4537
- * caller asks (OW-8, §4.5 rule 11).
4555
+ * caller asks (OW-8, §4.5 rule 11). Element files marked hidden travel too,
4556
+ * unless the caller says the file is a share (`includeHidden: false`, §4.8).
4538
4557
  *
4539
4558
  * A tool's own `.<tool>/` folder is the tool's (spec §4): the reader returns
4540
4559
  * it like any file (a caller leaves files out with `skip`), and the writer
@@ -4589,6 +4608,21 @@ interface OwWriteWorldFileOptions {
4589
4608
  * rule 11, OW-8). Left out or false, their directories are left out whole.
4590
4609
  */
4591
4610
  includePrivateRecords?: boolean;
4611
+ /**
4612
+ * Carry element files marked hidden (spec §4.8). Left out or true, they
4613
+ * travel byte for byte: a world file is a copy. Pass false when the file is
4614
+ * a share, made to hand to someone else: then every element file whose JSON
4615
+ * carries the hidden mark is left out whole, and `report` counts them. The
4616
+ * default is the opposite of `includePrivateRecords`'s on purpose.
4617
+ */
4618
+ includeHidden?: boolean;
4619
+ /** Called once with what the write left out, after the archive is made and before it is returned; never on a refusal. */
4620
+ report?: (report: OwWriteWorldFileReport) => void;
4621
+ }
4622
+ /** What `writeWorldFile` left out, handed to its `report` option. */
4623
+ interface OwWriteWorldFileReport {
4624
+ /** Element files left out for the hidden mark (`includeHidden: false`); 0 otherwise. */
4625
+ hiddenLeftOut: number;
4592
4626
  }
4593
4627
  /**
4594
4628
  * Write a world file under one top-level folder `topDir`: the `mimetype`
@@ -4608,8 +4642,19 @@ interface OwWriteWorldFileOptions {
4608
4642
  * to carry them; then the manifest is not read and every record travels. No
4609
4643
  * manifest, nothing is private.
4610
4644
  *
4645
+ * Element files marked hidden (spec §4.8) travel byte for byte by default: a
4646
+ * world file is a copy, also of a person's own world. A share is the offering
4647
+ * tool's question: pass `{ includeHidden: false }` for a file made to hand to
4648
+ * someone else, and every element file under `elements/<type>/` or
4649
+ * `spatial/<type>/` whose JSON carries a top-level `hidden` (anything but
4650
+ * absent, `null` or `false`) is left out whole. A file there that is not
4651
+ * JSON is kept. Nothing else is rewritten: a visible element's link to a
4652
+ * hidden one keeps its id, which then names no file. Pass
4653
+ * `report: r => …` to learn `r.hiddenLeftOut`, the count left out.
4654
+ *
4611
4655
  * Throws a `TypeError`, having written nothing, for an unknown option, an
4612
- * `includePrivateRecords` that is not a boolean, and (unless private records
4656
+ * `includePrivateRecords` or `includeHidden` that is not a boolean, a
4657
+ * `report` that is not a function, and (unless private records
4613
4658
  * are asked for) a `RECORDS.json` that is not a JSON array of objects or that
4614
4659
  * marks an entry private without a producer name. Refuses (`OwWorldFileError`)
4615
4660
  * an unsafe path or `topDir`, a duplicate path, a name some disk cannot hold,
@@ -5428,4 +5473,4 @@ declare class TokenResource {
5428
5473
  getEncryptionInfo(): Promise<EncryptionInfo>;
5429
5474
  }
5430
5475
 
5431
- export { AGENT_DOORS, ASK_LIMITS, type AccessKeyResponse, CALENDAR_FIELD, CALENDAR_SUPERTYPE, type CalendarConfig, type CalendarEra, type CalendarIntercalary, type CalendarMonths, type CalendarWeek, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementType, type EncryptionInfo, type EraDomain, FAMILY_COLORS, FAMILY_ORDER, FIELD_ACRONYMS, FIELD_SCHEMA, FILE_EXTENSIONS, type FieldInfo, type FieldType, GameTier, type ListParams, ONLYWORLDS_VERSION, type OwAccountWorld, type OwAgentJoined, type OwAllowance, OwApiError, type OwAskAnswer, type OwAskContext, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwCalendarElement, type OwChange, type OwChangeDelete, type OwChangeUpsert, type OwChangesPage, type OwClientConfig, type OwCreateAccountWorldInput, type OwCreatedAccountWorld, type OwCreatedWorldLink, type OwDeleteReason, type OwDraught, type OwDraughtComponent, type OwDraughtItem, type OwDraughtPolicy, type OwElement, type OwElementBase, type OwErrorBody, type OwFileAddedBy, type OwFileDownload, type OwFileKind, type OwFileRow, type OwFileTicket, type OwFrontDoor, type OwHiddenRow, type OwJoinPreview, type OwJoined, type OwJoinedMembership, type OwKeyKind, type OwLinkEdit, type OwLookupElement, type OwLookupHit, type OwLookupLink, type OwLookupOptions, type OwLookupReason, type OwMe, type OwMediaTicket, type OwMember, type OwMemberRole, type OwMintedKey, type OwNamesMap, OwNetworkError, type OwPage, type OwPhotoOptions, type OwPhotoPlan, type OwPlayerJoined, OwPreconditionFailedError, type OwPreparedPhoto, type OwProposal, type OwProposalAccepted, type OwProposalConflict, type OwProposalList, type OwProposalQuery, type OwProposalState, type OwProposeInput, type OwProposed, OwProposedError, type OwProposedNewElement, type OwReadWorldFile, type OwReadWorldFileOptions, type OwRemovalTicket, type OwRemovedImage, type OwRenderOptions, type OwResyncReason, type OwReviewInput, type OwReviewed, type OwSeat, type OwSeatCreated, type OwSignInBegin, type OwSignInBegun, type OwSignInComplete, OwSignInError, type OwSignInReason, type OwSignInResult, type OwSignInStorage, type OwSignedIn, type OwSortAddToRow, type OwSortAnswer, type OwSortAskRow, type OwSortLinkRow, type OwSortMakeRow, type OwSortNote, type OwSortRef, type OwSortRow, OwStaleProposalError, type OwUploadedFile, type OwUploadedImage, OwV2Client, type OwWordPair, type OwWorldFileEntry, OwWorldFileError, type OwWorldFileReason, type OwWorldFileRow, type OwWorldFiles, type OwWorldIndex, type OwWorldLink, type OwWorldMeta, type OwWorldOrigin, type OwWorldProducer, type OwWorldProposalList, type OwWorldProposalQuery, type OwWorldProposalRow, type OwWorldPublicPage, type OwWorldSource, type OwWriteDoor, type OwWriteWorldFileOptions, PHOTO_MAX_BYTES, PHOTO_TYPES, PUBLIC_FIELDS, type ParseError, type ParseOptions, type ParseResult, ROOM_PAIRS, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type StepBreakdown, type TokenConsumeParams, type TokenConsumeResponse, TokenResource, type TokenStatus, type TokenTransport, WORLD_FILE_MAX_BYTES, WORLD_FILE_MAX_ENTRIES, WORLD_FILE_MEDIA_TYPE, type WorldCalendar, absYearForEraYear, absoluteYear, approxYearLength, base64url, breakdownStep, buildAskContext, buildWorldIndex, detectKeyKind, displayYear, elementColor, eraForStep, errorFromResponse, familyOf, fieldLabel, fileKindOf, floorDiv, floorMod, formatDuration, formatMidLabel, formatStep, formatYearLabel, getElementIcon, getElementLabel, isAgentDoor, isDemoKey, isKnownOf, isLeapYear, isParseError, isRoomElement, kindCanWrite, lookupWorld, monthStartSteps, parseDate, parseErrorEnvelope, pinExpectation, pkceChallenge, planPhoto, preparePhoto, readCalendarConfig, readCalendarValue, readWorldFile, renderElement, resolveCalendarLens, resolveEraDomains, simpleCaseFold, typeWord, validateCalendarConfig, weekdayForStep, worldCalendars, writeWorldFile, yearLength, yearStartStep };
5476
+ export { AGENT_DOORS, ASK_LIMITS, type AccessKeyResponse, CALENDAR_FIELD, CALENDAR_SUPERTYPE, type CalendarConfig, type CalendarEra, type CalendarIntercalary, type CalendarMonths, type CalendarWeek, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementType, type EncryptionInfo, type EraDomain, FAMILY_COLORS, FAMILY_ORDER, FIELD_ACRONYMS, FIELD_SCHEMA, FILE_EXTENSIONS, type FieldInfo, type FieldType, GameTier, type ListParams, ONLYWORLDS_VERSION, type OwAccountWorld, type OwAgentJoined, type OwAllowance, OwApiError, type OwAskAnswer, type OwAskContext, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwCalendarElement, type OwChange, type OwChangeDelete, type OwChangeUpsert, type OwChangesPage, type OwClientConfig, type OwCreateAccountWorldInput, type OwCreatedAccountWorld, type OwCreatedWorldLink, type OwDeleteReason, type OwDraught, type OwDraughtCompact, type OwDraughtComponent, type OwDraughtItem, type OwDraughtPolicy, type OwElement, type OwElementBase, type OwErrorBody, type OwFileAddedBy, type OwFileDownload, type OwFileKind, type OwFileRow, type OwFileTicket, type OwFrontDoor, type OwHiddenRow, type OwJoinPreview, type OwJoined, type OwJoinedMembership, type OwKeyKind, type OwLinkEdit, type OwLookupElement, type OwLookupHit, type OwLookupLink, type OwLookupOptions, type OwLookupReason, type OwMe, type OwMediaTicket, type OwMember, type OwMemberRole, type OwMintedKey, type OwNamesMap, OwNetworkError, type OwPage, type OwPhotoOptions, type OwPhotoPlan, type OwPlayerJoined, OwPreconditionFailedError, type OwPreparedPhoto, type OwProposal, type OwProposalAccepted, type OwProposalConflict, type OwProposalList, type OwProposalQuery, type OwProposalState, type OwProposeInput, type OwProposed, OwProposedError, type OwProposedNewElement, type OwReadWorldFile, type OwReadWorldFileOptions, type OwRemovalTicket, type OwRemovedImage, type OwRenderOptions, type OwResyncReason, type OwReviewInput, type OwReviewed, type OwSeat, type OwSeatCreated, type OwSignInBegin, type OwSignInBegun, type OwSignInComplete, OwSignInError, type OwSignInReason, type OwSignInResult, type OwSignInStorage, type OwSignedIn, type OwSortAddToRow, type OwSortAnswer, type OwSortAskRow, type OwSortLinkRow, type OwSortMakeRow, type OwSortNote, type OwSortRef, type OwSortRow, OwStaleProposalError, type OwUploadedFile, type OwUploadedImage, OwV2Client, type OwWordPair, type OwWorldFileEntry, OwWorldFileError, type OwWorldFileReason, type OwWorldFileRow, type OwWorldFiles, type OwWorldIndex, type OwWorldLink, type OwWorldMeta, type OwWorldOrigin, type OwWorldProducer, type OwWorldProposalList, type OwWorldProposalQuery, type OwWorldProposalRow, type OwWorldPublicPage, type OwWorldSource, type OwWriteDoor, type OwWriteWorldFileOptions, type OwWriteWorldFileReport, PHOTO_MAX_BYTES, PHOTO_TYPES, PUBLIC_FIELDS, type ParseError, type ParseOptions, type ParseResult, ROOM_PAIRS, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type StepBreakdown, type TokenConsumeParams, type TokenConsumeResponse, TokenResource, type TokenStatus, type TokenTransport, WORLD_FILE_MAX_BYTES, WORLD_FILE_MAX_ENTRIES, WORLD_FILE_MEDIA_TYPE, type WorldCalendar, absYearForEraYear, absoluteYear, approxYearLength, base64url, breakdownStep, buildAskContext, buildWorldIndex, detectKeyKind, displayYear, elementColor, eraForStep, errorFromResponse, familyOf, fieldLabel, fileKindOf, floorDiv, floorMod, formatDuration, formatMidLabel, formatStep, formatYearLabel, getElementIcon, getElementLabel, isAgentDoor, isDemoKey, isKnownOf, isLeapYear, isParseError, isRoomElement, kindCanWrite, lookupWorld, monthStartSteps, parseDate, parseErrorEnvelope, pinExpectation, pkceChallenge, planPhoto, preparePhoto, readCalendarConfig, readCalendarValue, readWorldFile, renderElement, resolveCalendarLens, resolveEraDomains, simpleCaseFold, typeWord, validateCalendarConfig, weekdayForStep, worldCalendars, writeWorldFile, yearLength, yearStartStep };
package/dist/index.js CHANGED
@@ -690,22 +690,11 @@ var OwV2Client = class {
690
690
  });
691
691
  return this.request("GET", `/${type}/`, { query });
692
692
  }
693
- /**
694
- * GET /character/{id}/context -- the draught (keel PR 155, D143): what one Character knows, as the
695
- * recorded world holds it, in one read: her element, what she holds and sits in, her open work,
696
- * how she works, the Events she was in, the Narratives she knows, everything else that names
697
- * her, her sheet, what changed around her (`since`), and who plays whom; the world's name and
698
- * calendar beside; the room's messages (`messages`), its other elements (`room`, keel #556) and
699
- * elements written as proposed (`proposed`, keel #580) only when `components` names them. Each
700
- * row carries the list route's body for the same reader as `element`, beside `via`, `her_links`
701
- * and `grade`; nothing is inferred. The owner's keys, co-builders and contributors for any
702
- * Character they can see; a player seat or a guest for its own Character only (another id is
703
- * 404). `asOf` is a filter on the elements' own dates, not time travel. A `cut` that is not
704
- * empty means the serving is partial (`cut.proposed` also counts proposed elements left out because
705
- * the component was not named). Served `Cache-Control: private, no-store`.
706
- */
707
693
  async draught(characterId, policy = {}) {
708
- only("draught", policy, ["components", "mode", "asOf", "undated", "since", "budget", "depth"]);
694
+ only("draught", policy, ["components", "mode", "asOf", "undated", "since", "budget", "depth", "compact"]);
695
+ if (policy.compact !== void 0 && typeof policy.compact !== "boolean") {
696
+ throw new TypeError("draught: compact is true or false. Nothing was sent.");
697
+ }
709
698
  const query = buildQuery({
710
699
  components: policy.components?.join(","),
711
700
  mode: policy.mode,
@@ -713,7 +702,8 @@ var OwV2Client = class {
713
702
  undated: policy.undated,
714
703
  since: policy.since,
715
704
  budget: policy.budget,
716
- depth: policy.depth
705
+ depth: policy.depth,
706
+ compact: policy.compact
717
707
  });
718
708
  return this.request("GET", `/character/${characterId}/context`, { query });
719
709
  }
@@ -3360,17 +3350,36 @@ function carried(path) {
3360
3350
  return !segs.some((s) => s.startsWith(".")) && !path.endsWith(".meta");
3361
3351
  }
3362
3352
  var STAMP = new Date(1980, 0, 1, 0, 0, 0);
3363
- var WRITE_OPTION_KEYS = ["includePrivateRecords"];
3353
+ var WRITE_OPTION_KEYS = ["includePrivateRecords", "includeHidden", "report"];
3364
3354
  var RECORDS_MANIFEST = "records/RECORDS.json";
3365
- function asksPrivate(opts) {
3366
- if (opts === void 0 || opts === null) return false;
3355
+ function writeOptions(opts) {
3356
+ if (opts === void 0 || opts === null) return { includePrivate: false, includeHidden: true };
3367
3357
  if (typeof opts !== "object") throw new TypeError(`writeWorldFile: options must be an object, such as { includePrivateRecords: true }. Nothing was written.`);
3368
3358
  refuseUnknownOptions("writeWorldFile", opts, WRITE_OPTION_KEYS, "Nothing was written.");
3369
- const asked = opts.includePrivateRecords;
3370
- if (asked !== void 0 && typeof asked !== "boolean") {
3371
- throw new TypeError(`writeWorldFile: includePrivateRecords must be true or false; got ${JSON.stringify(asked) ?? String(asked)}. Nothing was written.`);
3359
+ const o = opts;
3360
+ for (const key of ["includePrivateRecords", "includeHidden"]) {
3361
+ const asked = o[key];
3362
+ if (asked !== void 0 && typeof asked !== "boolean") {
3363
+ throw new TypeError(`writeWorldFile: ${key} must be true or false; got ${JSON.stringify(asked) ?? String(asked)}. Nothing was written.`);
3364
+ }
3372
3365
  }
3373
- return asked === true;
3366
+ if (o.report !== void 0 && typeof o.report !== "function") {
3367
+ throw new TypeError(`writeWorldFile: report must be a function; got ${JSON.stringify(o.report) ?? String(o.report)}. Nothing was written.`);
3368
+ }
3369
+ return { includePrivate: o.includePrivateRecords === true, includeHidden: o.includeHidden !== false, report: o.report };
3370
+ }
3371
+ function isHiddenElement(f) {
3372
+ const segs = f.path.split("/");
3373
+ if (segs.length !== 3 || segs[0] !== "elements" && segs[0] !== "spatial" || !/\.json$/i.test(segs[2])) return false;
3374
+ let doc;
3375
+ try {
3376
+ doc = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(f.data));
3377
+ } catch {
3378
+ return false;
3379
+ }
3380
+ if (doc === null || typeof doc !== "object" || Array.isArray(doc)) return false;
3381
+ const mark = doc.hidden;
3382
+ return mark !== void 0 && mark !== null && mark !== false;
3374
3383
  }
3375
3384
  function privateProducers(files) {
3376
3385
  const manifest = files.find((f) => f.path === RECORDS_MANIFEST);
@@ -3396,7 +3405,7 @@ function privateProducers(files) {
3396
3405
  return out;
3397
3406
  }
3398
3407
  function writeWorldFile(files, topDir, opts = {}) {
3399
- const includePrivate = asksPrivate(opts);
3408
+ const { includePrivate, includeHidden, report } = writeOptions(opts);
3400
3409
  if (pathFault(topDir) || topDir.includes("/")) throw new OwWorldFileError("unsafe_path");
3401
3410
  const seen = /* @__PURE__ */ new Set();
3402
3411
  for (const f of files) {
@@ -3409,7 +3418,15 @@ function writeWorldFile(files, topDir, opts = {}) {
3409
3418
  const segs = path.split("/");
3410
3419
  return segs.length > 2 && segs[0] === "records" && left.has(foldName(segs[1]));
3411
3420
  };
3412
- const kept = files.filter((f) => carried(f.path) && !inPrivate(f.path));
3421
+ let hiddenLeftOut = 0;
3422
+ const kept = files.filter((f) => {
3423
+ if (!carried(f.path) || inPrivate(f.path)) return false;
3424
+ if (!includeHidden && isHiddenElement(f)) {
3425
+ hiddenLeftOut++;
3426
+ return false;
3427
+ }
3428
+ return true;
3429
+ });
3413
3430
  if (!kept.some((f) => f.path === WORLD_FILE)) throw new OwWorldFileError("not_a_world");
3414
3431
  const keys = kept.map((f) => `${topDir}/${f.path}`);
3415
3432
  for (const key of keys) {
@@ -3426,7 +3443,9 @@ function writeWorldFile(files, topDir, opts = {}) {
3426
3443
  if (f.path === WORLD_FILE) data = withoutLink(data, parseWorld(data)).data;
3427
3444
  input[`${topDir}/${f.path}`] = [data, { level: /\.json$/i.test(f.path) ? 6 : 0, mtime: STAMP }];
3428
3445
  }
3429
- return zipSync(input);
3446
+ const zip = zipSync(input);
3447
+ report?.({ hiddenLeftOut });
3448
+ return zip;
3430
3449
  }
3431
3450
 
3432
3451
  // src/room.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlyworlds/sdk",
3
- "version": "4.68.0",
3
+ "version": "4.70.0",
4
4
  "description": "TypeScript SDK for the OnlyWorlds API - build world-building applications with type safety",
5
5
  "type": "module",
6
6
  "exports": {