stitchkit 0.98.0 → 0.98.2

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/CHANGELOG.md CHANGED
@@ -15,6 +15,17 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
15
15
 
16
16
  ## [Unreleased]
17
17
 
18
+ ## [0.98.2] — 2026-09-27
19
+
20
+ ### Fixed
21
+
22
+ - `stitchkit/live` — prepending to a watched array preserves future copy bases,
23
+ so a sliding window sends the new head plus one copy run instead of rewriting
24
+ the window. Duplicate lookup advances through each signature bucket once;
25
+ full-value fallback and the delta wire format are unchanged.
26
+ - Package-scoped release commits now produce the same validated publication
27
+ artifacts as release trains; a green CI run no longer omits their npm tarball.
28
+
18
29
  ## [0.98.0] — 2026-09-26
19
30
 
20
31
  ### ⚠️ Breaking changes
@@ -73,7 +73,7 @@ import {
73
73
  deltaWins,
74
74
  diff,
75
75
  watchKeyString
76
- } from "../index-wdkt63w3.js";
76
+ } from "../index-wt743f7f.js";
77
77
  import"../index-1j8pm5t0.js";
78
78
  import {
79
79
  BoundedChannelPolicySchema,
@@ -14,7 +14,7 @@ import {
14
14
  diff,
15
15
  watchContract,
16
16
  watchKeyString
17
- } from "../index-wdkt63w3.js";
17
+ } from "../index-wt743f7f.js";
18
18
  import"../index-1j8pm5t0.js";
19
19
  import"../index-d9pk3td4.js";
20
20
  import {
@@ -69,6 +69,10 @@ function objectDiff(previous, next) {
69
69
  }
70
70
  function arrayDiff(previous, next) {
71
71
  const previousSignatures = previous.map(signature);
72
+ const nextSignatures = next.map(signature);
73
+ const remaining = new Map;
74
+ for (const value of nextSignatures)
75
+ remaining.set(value, (remaining.get(value) ?? 0) + 1);
72
76
  const positions = new Map;
73
77
  previousSignatures.forEach((value, index) => {
74
78
  const bucket = positions.get(value);
@@ -77,6 +81,7 @@ function arrayDiff(previous, next) {
77
81
  else
78
82
  positions.set(value, [index]);
79
83
  });
84
+ const offsets = new Map;
80
85
  const taken = new Set;
81
86
  const ops = [];
82
87
  let cursor = 0;
@@ -87,8 +92,9 @@ function arrayDiff(previous, next) {
87
92
  ops[ops.length - 1] = { o: "copy", from: last.from, count: last.count + 1 };
88
93
  return true;
89
94
  };
90
- for (const element of next) {
91
- const wanted = signature(element);
95
+ for (const [index, wanted] of nextSignatures.entries()) {
96
+ const element = next[index];
97
+ remaining.set(wanted, (remaining.get(wanted) ?? 0) - 1);
92
98
  const last = ops.at(-1);
93
99
  const continuation = last?.o === "copy" ? last.from + last.count : undefined;
94
100
  if (continuation !== undefined && continuation < previous.length && previousSignatures[continuation] === wanted && !taken.has(continuation)) {
@@ -98,7 +104,13 @@ function arrayDiff(previous, next) {
98
104
  continue;
99
105
  }
100
106
  const bucket = positions.get(wanted);
101
- const found = bucket?.find((index) => !taken.has(index));
107
+ let offset = offsets.get(wanted) ?? 0;
108
+ let found = bucket?.[offset];
109
+ while (found !== undefined && taken.has(found)) {
110
+ offset += 1;
111
+ found = bucket?.[offset];
112
+ }
113
+ offsets.set(wanted, found === undefined ? offset : offset + 1);
102
114
  if (found !== undefined) {
103
115
  taken.add(found);
104
116
  if (!extend(found))
@@ -106,7 +118,8 @@ function arrayDiff(previous, next) {
106
118
  cursor = found + 1;
107
119
  continue;
108
120
  }
109
- const counterpart = cursor < previous.length && !taken.has(cursor) ? cursor : undefined;
121
+ const candidate = previousSignatures[cursor];
122
+ const counterpart = candidate !== undefined && !taken.has(cursor) && !remaining.get(candidate) ? cursor : undefined;
110
123
  const nested = counterpart === undefined ? undefined : diff(previous[counterpart], element);
111
124
  if (counterpart !== undefined && nested !== undefined) {
112
125
  taken.add(counterpart);
@@ -1 +1 @@
1
- {"version":3,"file":"watch-delta.d.ts","sourceRoot":"","sources":["../../src/live/watch-delta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,6DAA6D;AAC7D,MAAM,MAAM,YAAY;AACtB,wEAAwE;AACtE;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACvE,+DAA+D;GAC7D;IAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAA;CAAE;AACxE,4DAA4D;GAC1D;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE/C,yCAAyC;AACzC,MAAM,MAAM,UAAU;AACpB,gEAAgE;AAC9D;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1C;IACE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACpD,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,GACD;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE,CAAC;AAEjE,eAAO,MAAM,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAUzB,CAAC;AAE3B,eAAO,MAAM,kBAAkB,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAc3B,CAAC;AAa7B;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAK7E;AAwGD;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAqCnE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpE"}
1
+ {"version":3,"file":"watch-delta.d.ts","sourceRoot":"","sources":["../../src/live/watch-delta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,6DAA6D;AAC7D,MAAM,MAAM,YAAY;AACtB,wEAAwE;AACtE;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACvE,+DAA+D;GAC7D;IAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAA;CAAE;AACxE,4DAA4D;GAC1D;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE/C,yCAAyC;AACzC,MAAM,MAAM,UAAU;AACpB,gEAAgE;AAC9D;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1C;IACE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACpD,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,GACD;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE,CAAC;AAEjE,eAAO,MAAM,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAUzB,CAAC;AAE3B,eAAO,MAAM,kBAAkB,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAc3B,CAAC;AAa7B;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAK7E;AA2HD;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAqCnE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.98.0",
3
+ "version": "0.98.2",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",