@onlyworlds/sdk 4.14.0 → 4.16.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 +2 -0
- package/CHANGELOG.md +24 -0
- package/README.md +2 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +15 -0
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -30,6 +30,8 @@ against live data). The v1 surface (`OnlyWorldsClient`, the `ElementType` enum)
|
|
|
30
30
|
- Offline or stale edits: pass `{ ifMatch: el.change_seq }` to `patch`/`editLinks` (since 4.9.0).
|
|
31
31
|
If the element moved, nothing is written and `OwPreconditionFailedError` (412) carries
|
|
32
32
|
`current`; the server never merges, the client decides.
|
|
33
|
+
- Polling: `changesHead()` (since 4.15.0) gives `{head, cursor}` without a page; walk only
|
|
34
|
+
when `head` moved past the head you last applied.
|
|
33
35
|
- World-meta changes do NOT appear in `/changes` — poll `GET /world` separately.
|
|
34
36
|
- Extension fields: `x_<toolname>_*` is the sanctioned namespace for tool-specific state;
|
|
35
37
|
unknown unprefixed fields 422. Extensions are capped at **64 KB per element** (422,
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ earlier history lives in git log only.
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [4.16.0] — 2026-10-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`epoch` on the feed** (keel 979eb0c). `OwChangesPage.epoch` and `changesHead()`'s
|
|
12
|
+
`epoch`: a guest's view epoch (an integer), `null` for every other key. It moves when what a
|
|
13
|
+
guest may see changes, even with `head` unchanged, so a poll walks when either `head` or
|
|
14
|
+
`epoch` moved; nothing needs to read inside the cursor. `changesHead()` answers
|
|
15
|
+
`epoch: null` from a keel without the field. Checked live on Moppetopia (the head read and a
|
|
16
|
+
page both carry `epoch: null`). The wire gate now holds `OwChangesPage` and `OwBulkResponse`
|
|
17
|
+
to keel's `ChangesPage` and `BulkResult` (keel #108), and failed on 4.15.0 for the missing
|
|
18
|
+
`epoch` before this release.
|
|
19
|
+
|
|
20
|
+
## [4.15.0] — 2026-10-12
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- **`changesHead()`**: `GET /changes?head=true`, the feed's position now without a page
|
|
24
|
+
(keel reads no element). Returns `{ head, cursor }`: `head` is the world's `change_seq`,
|
|
25
|
+
`cursor` a position to pass as `since` that re-sends nothing (a guest's carries its view's
|
|
26
|
+
epoch). The cheap "anything new?" for a poll: compare `head` with the head you last applied
|
|
27
|
+
and walk `changesAll` only when it moved. keel sends the owner's cursor as a number; it comes
|
|
28
|
+
back as a string, like every cursor the SDK hands out. Checked live on Moppetopia: a walk
|
|
29
|
+
from the returned cursor brings nothing. Asked for by Lantern's 20-second poll (Temper,
|
|
30
|
+
Skeld's S15).
|
|
31
|
+
|
|
8
32
|
## [4.14.0] — 2026-10-12
|
|
9
33
|
|
|
10
34
|
### Fixed
|
package/README.md
CHANGED
|
@@ -130,6 +130,8 @@ for await (const change of client.changesAll(cursor)) {
|
|
|
130
130
|
}
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
+
To poll for news cheaply, `client.changesHead()` returns `{ head, cursor }` without reading any element: walk `changesAll` only when `head` moved past the head you last applied.
|
|
134
|
+
|
|
133
135
|
Edits to the world itself (its name, calendar, `public_read`) don't appear in the change feed. Read `client.getWorld()` and compare `updated_at`.
|
|
134
136
|
|
|
135
137
|
### Only if unchanged
|
package/dist/index.d.ts
CHANGED
|
@@ -1901,6 +1901,12 @@ interface OwChangesPage {
|
|
|
1901
1901
|
* instead of assuming caught-up.
|
|
1902
1902
|
*/
|
|
1903
1903
|
head: number;
|
|
1904
|
+
/**
|
|
1905
|
+
* A guest's view epoch (an integer), null for every other key. It moves when what the
|
|
1906
|
+
* guest may see changes, even with `head` unchanged (a Character given or taken, a role):
|
|
1907
|
+
* walk again on either move. Compare it, never read it out of the cursor (keel, 2026-10-12).
|
|
1908
|
+
*/
|
|
1909
|
+
epoch: number | null;
|
|
1904
1910
|
}
|
|
1905
1911
|
interface OwBulkItem {
|
|
1906
1912
|
type: ElementType | string;
|
|
@@ -2363,6 +2369,22 @@ declare class OwV2Client {
|
|
|
2363
2369
|
since?: string;
|
|
2364
2370
|
limit?: number;
|
|
2365
2371
|
}): Promise<OwChangesPage>;
|
|
2372
|
+
/**
|
|
2373
|
+
* GET /changes?head=true -- where the feed is now, without a page: no element is read.
|
|
2374
|
+
* `head` is the world's change_seq; `cursor` is a position to pass as `since` that
|
|
2375
|
+
* re-sends nothing at the head (a guest's carries its view's epoch). The cheap "anything
|
|
2376
|
+
* new?" for a poll: compare `head` with the head you last APPLIED (not the previous
|
|
2377
|
+
* poll's, so a missed tick never drops a change) and walk changesAll only when it moved;
|
|
2378
|
+
* a head below yours means the server rewound: walk again from zero. `epoch` is a
|
|
2379
|
+
* guest's view epoch (null for other keys): it can move with `head` unchanged, so walk on
|
|
2380
|
+
* either move. keel returns the owner's cursor as a number; it is handed back as a
|
|
2381
|
+
* string, like every cursor here.
|
|
2382
|
+
*/
|
|
2383
|
+
changesHead(): Promise<{
|
|
2384
|
+
head: number;
|
|
2385
|
+
cursor: string;
|
|
2386
|
+
epoch: number | null;
|
|
2387
|
+
}>;
|
|
2366
2388
|
/**
|
|
2367
2389
|
* Walk the feed from `since` (or from zero = full export) to the current
|
|
2368
2390
|
* tail, yielding ops in order. Returns the final cursor via the generator's
|
package/dist/index.js
CHANGED
|
@@ -329,6 +329,21 @@ var OwV2Client = class {
|
|
|
329
329
|
const query = buildQuery({ since: opts.since, limit: opts.limit ?? this.changesPageSize });
|
|
330
330
|
return this.request("GET", "/changes/", { query });
|
|
331
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* GET /changes?head=true -- where the feed is now, without a page: no element is read.
|
|
334
|
+
* `head` is the world's change_seq; `cursor` is a position to pass as `since` that
|
|
335
|
+
* re-sends nothing at the head (a guest's carries its view's epoch). The cheap "anything
|
|
336
|
+
* new?" for a poll: compare `head` with the head you last APPLIED (not the previous
|
|
337
|
+
* poll's, so a missed tick never drops a change) and walk changesAll only when it moved;
|
|
338
|
+
* a head below yours means the server rewound: walk again from zero. `epoch` is a
|
|
339
|
+
* guest's view epoch (null for other keys): it can move with `head` unchanged, so walk on
|
|
340
|
+
* either move. keel returns the owner's cursor as a number; it is handed back as a
|
|
341
|
+
* string, like every cursor here.
|
|
342
|
+
*/
|
|
343
|
+
async changesHead() {
|
|
344
|
+
const page = await this.request("GET", "/changes/", { query: buildQuery({ head: "true" }) });
|
|
345
|
+
return { head: page.head, cursor: String(page.cursor), epoch: page.epoch ?? null };
|
|
346
|
+
}
|
|
332
347
|
/**
|
|
333
348
|
* Walk the feed from `since` (or from zero = full export) to the current
|
|
334
349
|
* tail, yielding ops in order. Returns the final cursor via the generator's
|