Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changeset/fix-jsx-clean-teardown-race.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
"@tko/utils.jsx": patch
"@tko/utils.jsx": minor
---

Add `options.jsxCleanBatchSize` (default `1000`) controlling JSX node cleanup
Expand Down
28 changes: 19 additions & 9 deletions .changeset/modernize-utils-dead-polyfills.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
---
"@tko/utils": minor
"@tko/utils": patch
"@tko/utils.parser": patch
"@tko/observable": patch
"@tko/binding.core": patch
"@tko/binding.foreach": patch
"@tko/computed": patch
"@tko/lifecycle": patch
"@tko/builder": minor
"@tko/builder": patch
---

Drop dead polyfill probes from `@tko/utils`

Removes runtime feature detection for capabilities that all supported runtimes
(modern browsers, Node, Bun, happy-dom) already expose unconditionally:
(modern browsers, Node, Bun, happy-dom) already expose unconditionally. The
public API surface is preserved as one-line passthroughs in
`packages/utils/src/compat.ts` so existing consumers continue to work; these
shims are slated for removal in the next major.

- `functionSupportsLengthOverwrite` + `overwriteLengthPropertyIfSupported` —
`Object.defineProperty(fn, 'length', …)` has worked since IE9. Call sites
in `@tko/observable` now invoke `Object.defineProperty` directly.
in `@tko/observable` now invoke `Object.defineProperty` directly. The
internal probe is gone; `overwriteLengthPropertyIfSupported` is preserved
on `@tko/utils` exports as an inline `Object.defineProperty` call.
- `useSymbols` + `createSymbolOrString` — `Symbol` is always defined; call
sites now use `Symbol(identifier)` directly. `createSymbolOrString` is no
longer exposed on `ko.utils` (public API removal — minor bump for
`@tko/utils` and `@tko/builder`).
- `stringTrim` + `stringStartsWith` — removed; call sites use
`String(value ?? '').trim()` / `value.startsWith(prefix)` inline.
sites now use `Symbol(identifier)` directly. `createSymbolOrString` is
preserved as `s => Symbol(s)` on both `@tko/utils` exports and
`ko.utils.createSymbolOrString`.
- `stringTrim` + `stringStartsWith` — call sites use `String(value ?? '')
.trim()` / `value.startsWith(prefix)` inline. Both names remain exported
from `@tko/utils` as inline passthroughs.
- `toggleDomNodeCssClass` SVGAnimatedString fallback — `classList` is
available on every supported `Element` (including SVG since SVG2).
- `parseJson` no longer routes through `stringTrim`; it trims inline when the
Expand All @@ -31,3 +37,7 @@ Removes runtime feature detection for capabilities that all supported runtimes
`packages/utils.parser/src/preparse.ts` also guards `str.match(bindingToken)`
against the `null` return case using `?? []` — previously relied on the match
never returning `null` for the transformed input.

Patch-level for all packages: zero observable surface change for consumers
not reaching into internal probes (`useSymbols`, `functionSupportsLengthOverwrite`),
which had no monorepo callers.
21 changes: 0 additions & 21 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions packages/bind/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
"@tko/utils": "^4.0.1",
"@tko/builder": "^4.0.1"
},
"peerDependencies": {
"@tko/binding.foreach": "^4.0.1"
},
"files": [
"dist/"
],
Expand Down
3 changes: 0 additions & 3 deletions packages/binding.template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
"@tko/observable": "^4.0.1",
"@tko/utils": "^4.0.1"
},
"peerDependencies": {
"@tko/binding.if": "^4.0.1"
},
"licenses": [
{
"type": "MIT",
Expand Down
3 changes: 3 additions & 0 deletions packages/builder/src/Builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
cleanNode,
cloneNodes,
compareArrays,
createSymbolOrString,
domData,
extend,
memoization,
Expand Down Expand Up @@ -115,6 +116,7 @@ export type Utils = {
arrayRemoveItem: typeof arrayRemoveItem
cloneNodes: typeof cloneNodes
compareArrays: typeof compareArrays
createSymbolOrString: typeof createSymbolOrString
domData: typeof domData
domNodeDisposal: typeof domNodeDisposal
extend: typeof extend
Expand Down Expand Up @@ -147,6 +149,7 @@ const utils: Utils = {
arrayRemoveItem,
cloneNodes,
compareArrays,
createSymbolOrString,
domData,
domNodeDisposal,
extend,
Expand Down
4 changes: 1 addition & 3 deletions packages/lifecycle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
"module": "dist/index.js",
"dependencies": {
"@tko/computed": "^4.0.1",
"@tko/observable": "^4.0.1",
"@tko/utils": "^4.0.1"
},
Comment on lines 5 to 8
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep observable as declared dependency for lifecycle types

Removing @tko/observable from peerDependencies leaves @tko/lifecycle with a public type surface that still references that package (import type { Observable } in LifeCycle.subscribe), so emitted declarations require consumers to resolve @tko/observable. Under non-hoisting/isolated installs (for example strict pnpm-style layouts), relying on it as only a transitive dependency through @tko/computed can make @tko/lifecycle type resolution fail with TS2307.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. LifeCycle.subscribe(observable: Observable, ...) is a public method, so Observable lands in the emitted .d.ts — strict-isolation installs (pnpm, yarn pnp) need @tko/observable resolvable directly, and the transitive path through @tko/computed only works under flat hoisting.

Fixed in 8c35203f by adding @tko/observable back to @tko/lifecycle's dependencies (its proper home for type-imports in public surface — peerDependencies was overkill, but full removal was too much).

I audited the other four packages where peerDeps were dropped — none of their src/ files reference the removed peers (the imports were all in spec/ only), so no public type surface depends on them. Lifecycle was the only one with this concern.


Generated by Claude Code

"peerDependencies": {
"@tko/observable": "^4.0.1"
},
"files": [
"dist/"
],
Expand Down
7 changes: 0 additions & 7 deletions packages/utils.component/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@
"@tko/observable": "^4.0.1",
"@tko/utils": "^4.0.1"
},
"peerDependencies": {
"@tko/bind": "^4.0.1",
"@tko/binding.core": "^4.0.1",
"@tko/computed": "^4.0.1",
"@tko/provider.multi": "^4.0.1",
"@tko/provider.virtual": "^4.0.1"
},
"homepage": "https://tko.io",
"licenses": [
{
Expand Down
5 changes: 0 additions & 5 deletions packages/utils.parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
"@tko/observable": "^4.0.1",
"@tko/utils": "^4.0.1"
},
"peerDependencies": {
"@tko/bind": "^4.0.1",
"@tko/binding.core": "^4.0.1",
"@tko/provider.databind": "^4.0.1"
},
"homepage": "https://tko.io",
"licenses": [
{
Expand Down
34 changes: 34 additions & 0 deletions packages/utils/src/compat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Compat passthroughs preserving the public @tko/utils API after the
// post-Symbol/post-IE9 polyfill removals. Each function delegates to a
// native API; kept so consumers importing these names continue to work.
// All entries here are slated for removal in the next major version.

/**
* @deprecated Use `Symbol(identifier)` directly. Will be removed in a future major.
*/
export function createSymbolOrString(identifier: string): symbol {
return Symbol(identifier)
}

/**
* @deprecated Use `String(value ?? '').trim()` directly (or `String.prototype.trim`
* when the input is known to be a string). Will be removed in a future major.
*/
export function stringTrim(value: any): string {
return String(value ?? '').trim()
}

/**
* @deprecated Use `String.prototype.startsWith` directly. Will be removed in a future major.
*/
export function stringStartsWith(value: string, prefix: string): boolean {
return (value ?? '').startsWith(prefix)
}

/**
* @deprecated Use `Object.defineProperty(fn, 'length', descriptor)` directly.
* Will be removed in a future major.
*/
export function overwriteLengthPropertyIfSupported(fn: Function, descriptor: PropertyDescriptor): void {
Object.defineProperty(fn, 'length', descriptor)
}
1 change: 1 addition & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

export * from './array'
export * from './async'
export * from './compat'
export * from './error'
export * from './object'
export * from './string'
Expand Down
Loading