Skip to content

Commit

Permalink
fix: Fix Typescript 5.6.x support by introducing esnext iterator help…
Browse files Browse the repository at this point in the history
…ers (#3927) (#3935)

* Update typescript version

* Chore(map + set): Add support for esnext Iterator helpers

* add changeset

* Update lock file
  • Loading branch information
tonyraoul authored Oct 15, 2024
1 parent 70762a0 commit f91d2e1
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 28 deletions.
5 changes: 5 additions & 0 deletions .changeset/neat-ants-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"mobx": patch
---

Update typescript version to 5.6.2 and added support for esnext iterator helpers
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
],
"resolutions": {
"jest": "^29.5.0",
"typescript": "^5.5.2",
"typescript": "^5.6.2",
"recast": "^0.23.1"
},
"repository": {
Expand Down Expand Up @@ -69,7 +69,7 @@
"tape": "^5.0.1",
"ts-jest": "^29.0.5",
"tsdx": "^0.14.1",
"typescript": "^5.5.2"
"typescript": "^5.6.2"
},
"husky": {
"hooks": {
Expand Down
28 changes: 28 additions & 0 deletions packages/mobx/__tests__/v5/base/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,34 @@ test("maps.values, keys and maps.entries are iterables", () => {
expect(Array.from(x.keys())).toEqual(["x", "y"])
})

// Test support for [iterator-helpers](https://github.com/tc39/proposal-iterator-helpers)
test("esnext iterator helpers support", () => {
const map = mobx.observable(
new Map([
["x", [1, 2]],
["y", [3, 4]]
])
)

expect(Array.from(map.keys().map(value => value))).toEqual(["x", "y"])
expect(Array.from(map.values().map(value => value))).toEqual([
[1, 2],
[3, 4]
])
expect(Array.from(map.entries().map(([, value]) => value))).toEqual([
[1, 2],
[3, 4]
])

expect(Array.from(map.entries().take(1))).toEqual([["x", [1, 2]]])
expect(Array.from(map.entries().drop(1))).toEqual([["y", [3, 4]]])
expect(Array.from(map.entries().filter(([key]) => key === "y"))).toEqual([["y", [3, 4]]])
expect(Array.from(map.entries().find(([key]) => key === "y"))).toEqual(["y", [3, 4]])
expect(map.entries().toArray()).toEqual(Array.from(map))

expect(map.entries().toString()).toEqual("[object MapIterator]")
})

test("toStringTag", () => {
const x = mobx.observable.map({ x: 1, y: 2 })
expect(x[Symbol.toStringTag]).toBe("Map")
Expand Down
28 changes: 28 additions & 0 deletions packages/mobx/__tests__/v5/base/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,34 @@ test("set should support iterall / iterable ", () => {
expect(leech(a.values())).toEqual([1, 2])
})

// Test support for [iterator-helpers](https://github.com/tc39/proposal-iterator-helpers)
test("esnext iterator helpers support", () => {
const set = mobx.observable(
new Set([
[1, 2],
[3, 4]
])
)

expect(Array.from(set.values().map(value => value))).toEqual([
[1, 2],
[3, 4]
])

expect(Array.from(set.entries().map(([, value]) => value))).toEqual([
[1, 2],
[3, 4]
])

expect(Array.from(set.values().take(1))).toEqual([[1, 2]])
expect(Array.from(set.values().drop(1))).toEqual([[3, 4]])
expect(Array.from(set.values().filter(value => value[0] === 3))).toEqual([[3, 4]])
expect(Array.from(set.values().find(value => value[0] === 3))).toEqual([3, 4])
expect(Array.from(set.values().flatMap(value => value))).toEqual([1, 2, 3, 4])

expect(set.entries().toString()).toEqual("[object SetIterator]")
})

test("support for ES6 Set", () => {
const x = new Set()
x.add(1)
Expand Down
17 changes: 11 additions & 6 deletions packages/mobx/src/types/observablemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
checkIfStateModificationsAreAllowed,
createAtom,
createInstanceofPredicate,
makeIterable,
deepEnhancer,
getNextId,
getPlainObjectKeys,
Expand All @@ -19,7 +20,6 @@ import {
isPlainES6Map,
isPlainObject,
isSpyEnabled,
makeIterable,
notifyListeners,
referenceEnhancer,
registerInterceptor,
Expand Down Expand Up @@ -296,15 +296,15 @@ export class ObservableMap<K = any, V = any>
return value
}

keys(): IterableIterator<K> {
keys(): MapIterator<K> {
this.keysAtom_.reportObserved()
return this.data_.keys()
}

values(): IterableIterator<V> {
values(): MapIterator<V> {
const self = this
const keys = this.keys()
return makeIterable({
return makeIterableForMap({
next() {
const { done, value } = keys.next()
return {
Expand All @@ -315,10 +315,10 @@ export class ObservableMap<K = any, V = any>
})
}

entries(): IterableIterator<IMapEntry<K, V>> {
entries(): MapIterator<IMapEntry<K, V>> {
const self = this
const keys = this.keys()
return makeIterable({
return makeIterableForMap({
next() {
const { done, value } = keys.next()
return {
Expand Down Expand Up @@ -490,6 +490,11 @@ export var isObservableMap = createInstanceofPredicate("ObservableMap", Observab
thing: any
) => thing is ObservableMap<any, any>

function makeIterableForMap<T>(iterator: Iterator<T>): MapIterator<T> {
iterator[Symbol.toStringTag] = "MapIterator"
return makeIterable<T, BuiltinIteratorReturn>(iterator)
}

function convertToMap(dataStructure: any): Map<any, any> {
if (isES6Map(dataStructure) || isObservableMap(dataStructure)) {
return dataStructure
Expand Down
23 changes: 14 additions & 9 deletions packages/mobx/src/types/observableset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import {
notifyListeners,
spyReportEnd,
createInstanceofPredicate,
makeIterable,
hasInterceptors,
interceptChange,
IInterceptable,
IInterceptor,
registerInterceptor,
checkIfStateModificationsAreAllowed,
untracked,
makeIterable,
transaction,
isES6Set,
IAtom,
Expand Down Expand Up @@ -214,33 +214,33 @@ export class ObservableSet<T = any> implements Set<T>, IInterceptable<ISetWillCh
let nextIndex = 0
const keys = Array.from(this.keys())
const values = Array.from(this.values())
return makeIterable<[T, T]>({
return makeIterableForSet<[T, T]>({
next() {
const index = nextIndex
nextIndex += 1
return index < values.length
? { value: [keys[index], values[index]], done: false }
: { done: true }
: { value: undefined, done: true }
}
} as any)
})
}

keys(): IterableIterator<T> {
keys(): SetIterator<T> {
return this.values()
}

values(): IterableIterator<T> {
values(): SetIterator<T> {
this.atom_.reportObserved()
const self = this
let nextIndex = 0
const observableValues = Array.from(this.data_.values())
return makeIterable<T>({
return makeIterableForSet({
next() {
return nextIndex < observableValues.length
? { value: self.dehanceValue_(observableValues[nextIndex++]), done: false }
: { done: true }
: { value: undefined, done: true }
}
} as any)
})
}

intersection<U>(otherSet: ReadonlySetLike<U> | Set<U>): Set<T & U> {
Expand Down Expand Up @@ -343,3 +343,8 @@ export class ObservableSet<T = any> implements Set<T>, IInterceptable<ISetWillCh
export var isObservableSet = createInstanceofPredicate("ObservableSet", ObservableSet) as (
thing: any
) => thing is ObservableSet<any>

function makeIterableForSet<T>(iterator: Iterator<T>): SetIterator<T> {
iterator[Symbol.toStringTag] = "SetIterator"
return makeIterable<T, BuiltinIteratorReturn>(iterator)
}
11 changes: 4 additions & 7 deletions packages/mobx/src/utils/iterable.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
export function makeIterable<T>(iterator: Iterator<T>): IterableIterator<T> {
iterator[Symbol.iterator] = getSelf
return iterator as any
}

function getSelf() {
return this
export function makeIterable<T, TReturn = unknown>(
iterator: Iterator<T>
): IteratorObject<T, TReturn> {
return Object.assign(Object.create(Iterator.prototype), iterator)
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13579,10 +13579,10 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==

typescript@^3.7.3, typescript@^5.5.2:
version "5.5.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.2.tgz#c26f023cb0054e657ce04f72583ea2d85f8d0507"
integrity sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==
typescript@^3.7.3, typescript@^5.6.2:
version "5.6.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0"
integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==

uglify-js@^3.1.4:
version "3.17.4"
Expand Down

0 comments on commit f91d2e1

Please sign in to comment.