Skip to content

Commit

Permalink
Shrink Atom and Reaction using a bitfield
Browse files Browse the repository at this point in the history
  • Loading branch information
peterm-canva committed Jul 8, 2024
2 parents 39a0074 + a73710c commit c8b91d5
Show file tree
Hide file tree
Showing 19 changed files with 3,884 additions and 3,165 deletions.
7 changes: 0 additions & 7 deletions .changeset/lovely-lemons-joke.md

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
- name: Checkout Repo
uses: actions/checkout@master

- name: Setup Node.js 20.x
- name: Setup Node.js 22.x
uses: actions/setup-node@master
with:
node-version: 20.x
node-version: 22.x

- name: Install Dependencies
run: yarn --frozen-lockfile --ignore-scripts
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/coveralls.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0

- name: Setup Node.js 20.x
- name: Setup Node.js 22.x
uses: actions/setup-node@master
with:
node-version: 20.x
node-version: 22.x

- name: Install Dependencies
run: yarn --frozen-lockfile --ignore-scripts
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0

- name: Setup Node.js 20.x
- name: Setup Node.js 22.x
uses: actions/setup-node@master
with:
node-version: 20.x
node-version: 22.x

- name: Install Dependencies
run: yarn
Expand Down
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.0.2",
"typescript": "^5.5.2",
"recast": "^0.23.1"
},
"repository": {
Expand Down Expand Up @@ -68,7 +68,7 @@
"tape": "^5.0.1",
"ts-jest": "^29.0.5",
"tsdx": "^0.14.1",
"typescript": "^5.0.2"
"typescript": "^5.5.2"
},
"husky": {
"hooks": {
Expand Down
8 changes: 8 additions & 0 deletions packages/eslint-plugin-mobx/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# eslint-plugin-mobx

## 0.0.10

### Patch Changes

- [`44a5fe07`](https://github.com/mobxjs/mobx/commit/44a5fe07fb95c2ba24d8df19f18b57ee92abb1a9) [#3881](https://github.com/mobxjs/mobx/pull/3881) Thanks [@kade-robertson](https://github.com/kade-robertson)! - Adds an option for the `mobx/exhaustive-make-observable` eslint rule to configure whether fields are annotated with `true` or `false` with the autofixer.

This option defaults to `true` if not present or an invalid value is received to maintain existing behavior.

## 0.0.9

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-mobx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-mobx",
"version": "0.0.9",
"version": "0.0.10",
"description": "ESLint rules for MobX",
"main": "dist/index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/mobx-react-lite/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"lib": ["es6", "DOM"]
"lib": ["ESNext", "DOM"]
},
"include": ["src"]
}
28 changes: 23 additions & 5 deletions packages/mobx/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# mobx

## 6.13.0

### Minor Changes

- [`16f070e6aac60e9010c2591b1743276d700b23d5`](https://github.com/mobxjs/mobx/commit/16f070e6aac60e9010c2591b1743276d700b23d5) [#3898](https://github.com/mobxjs/mobx/pull/3898) Thanks [@inoyakaigor](https://github.com/inoyakaigor)! - Added new Set methods

## 6.12.5

### Patch Changes

- [`ba890343`](https://github.com/mobxjs/mobx/commit/ba8903430ce96746db5dcde6b78edeb195ea8018) [#3893](https://github.com/mobxjs/mobx/pull/3893) Thanks [@g6123](https://github.com/g6123)! - Fix ES6 Map/Set checks for cross-window scripts

## 6.12.4

### Patch Changes

- [`e9e1955f`](https://github.com/mobxjs/mobx/commit/e9e1955f745545d796d906b6e0ba04a6cde3f1ee) [#3880](https://github.com/mobxjs/mobx/pull/3880) Thanks [@peterm-canva](https://github.com/peterm-canva)! - Shrink ComputedValue using a bitfield

## 6.12.2

### Patch Changes
Expand Down Expand Up @@ -1390,7 +1408,7 @@ A deprecation message will now be printed if creating computed properties while

```javascript
const x = observable({
computedProp: function() {
computedProp: function () {
return someComputation
}
})
Expand All @@ -1415,7 +1433,7 @@ or alternatively:

```javascript
observable({
computedProp: computed(function() {
computedProp: computed(function () {
return someComputation
})
})
Expand All @@ -1433,7 +1451,7 @@ N.B. If you want to introduce actions on an observable that modify its state, us
```javascript
observable({
counter: 0,
increment: action(function() {
increment: action(function () {
this.counter++
})
})
Expand Down Expand Up @@ -1559,10 +1577,10 @@ function Square() {
extendObservable(this, {
length: 2,
squared: computed(
function() {
function () {
return this.squared * this.squared
},
function(surfaceSize) {
function (surfaceSize) {
this.length = Math.sqrt(surfaceSize)
}
)
Expand Down
139 changes: 139 additions & 0 deletions packages/mobx/__tests__/v5/base/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,142 @@ test("set.forEach is reactive", () => {
s.add(2)
expect(c).toBe(3)
})

describe("The Set object methods do what they are supposed to do", () => {
const reactiveSet = set([1, 2, 3, 4, 5])

test("Observable Set methods returns correct result", () => {
const intersectionObservableResult = reactiveSet.intersection(new Set([1, 2, 6]))
const unionObservableResult = reactiveSet.union(new Set([1, 2, 6]))
const differenceObservableResult = reactiveSet.difference(new Set([1, 2, 3, 4, 5, 6, 7]))
const symmetricDifferenceObservableResult = reactiveSet.symmetricDifference(new Set([3, 4]))
const isSubsetOfObservableResult = reactiveSet.isSubsetOf(new Set([1, 2, 3]))
const isSupersetOfObservableResult = reactiveSet.isSupersetOf(new Set([1, 2, 3, 4, 5, 6]))
const isDisjointFromObservableResult = reactiveSet.isDisjointFrom(new Set([6, 7]))

expect(intersectionObservableResult).toEqual(new Set([1, 2]))
expect(unionObservableResult).toEqual(new Set([1, 2, 3, 4, 5, 6]))
expect(differenceObservableResult).toEqual(new Set())
expect(symmetricDifferenceObservableResult).toEqual(new Set([1, 2, 5]))
expect(isSubsetOfObservableResult).toBeFalsy()
expect(isSupersetOfObservableResult).toBeFalsy()
expect(isDisjointFromObservableResult).toBeTruthy()
})

test("Observable Set proper works with Set-like objects", () => {
const intersectionObservableResult = reactiveSet.intersection(
new Map([1, 2, 6].map(i => [i, i]))
)
const unionObservableResult = reactiveSet.union(new Map([1, 2, 6].map(i => [i, i])))
const differenceObservableResult = reactiveSet.difference(
new Map([1, 2, 3, 4, 5, 6, 7].map(i => [i, i]))
)
const symmetricDifferenceObservableResult = reactiveSet.symmetricDifference(
new Map([3, 4].map(i => [i, i]))
)
const isSubsetOfObservableResult = reactiveSet.isSubsetOf(
new Map([1, 2, 3].map(i => [i, i]))
)
const isSupersetOfObservableResult = reactiveSet.isSupersetOf(
new Map([1, 2, 3, 4, 5, 6].map(i => [i, i]))
)
const isDisjointFromObservableResult = reactiveSet.isDisjointFrom(
new Map([6, 7].map(i => [i, i]))
)

expect(intersectionObservableResult).toEqual(new Set([1, 2]))
expect(unionObservableResult).toEqual(new Set([1, 2, 3, 4, 5, 6]))
expect(differenceObservableResult).toEqual(new Set())
expect(symmetricDifferenceObservableResult).toEqual(new Set([1, 2, 5]))
expect(isSubsetOfObservableResult).toBeFalsy()
expect(isSupersetOfObservableResult).toBeFalsy()
expect(isDisjointFromObservableResult).toBeTruthy()
})
})

describe("Observable Set methods are reactive", () => {
let c = 0
let s = set()

beforeEach(() => {
c = 0
s = set()
})

test("Intersection method is reactive", () => {
autorun(() => {
s.intersection(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("Union method is reactive", () => {
autorun(() => {
s.union(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("Difference method is reactive", () => {
autorun(() => {
s.difference(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("symmetricDifference method is reactive", () => {
autorun(() => {
s.symmetricDifference(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("isSubsetOf method is reactive", () => {
autorun(() => {
s.isSubsetOf(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("isSupersetOf method is reactive", () => {
autorun(() => {
s.isSupersetOf(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})

test("isDisjointFrom method is reactive", () => {
autorun(() => {
s.isDisjointFrom(new Set())
c++
})

s.add(1)
s.add(2)
expect(c).toBe(3)
})
})
2 changes: 1 addition & 1 deletion packages/mobx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mobx",
"version": "6.12.3",
"version": "6.13.0",
"description": "Simple, scalable state management.",
"source": "src/mobx.ts",
"main": "dist/index.js",
Expand Down
4 changes: 2 additions & 2 deletions packages/mobx/src/core/atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ export class Atom implements IAtom {
this.flags_ = setFlag(this.flags_, Atom.isPendingUnobservationMask_, newValue)
}

get diffValue(): number {
get diffValue(): 0 | 1 {
return getFlag(this.flags_, Atom.diffValueMask_) ? 1 : 0
}
set diffValue(newValue: number) {
set diffValue(newValue: 0 | 1) {
this.flags_ = setFlag(this.flags_, Atom.diffValueMask_, newValue === 1 ? true : false)
}

Expand Down
4 changes: 2 additions & 2 deletions packages/mobx/src/core/computedvalue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
this.flags_ = setFlag(this.flags_, ComputedValue.isPendingUnobservationMask_, newValue)
}

get diffValue(): number {
get diffValue(): 0 | 1 {
return getFlag(this.flags_, ComputedValue.diffValueMask_) ? 1 : 0
}
set diffValue(newValue: number) {
set diffValue(newValue: 0 | 1) {
this.flags_ = setFlag(
this.flags_,
ComputedValue.diffValueMask_,
Expand Down
4 changes: 2 additions & 2 deletions packages/mobx/src/core/reaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ export class Reaction implements IDerivation, IReactionPublic {
this.flags_ = setFlag(this.flags_, Reaction.isRunningMask_, newValue)
}

get diffValue(): number {
get diffValue(): 0 | 1 {
return getFlag(this.flags_, Reaction.diffValueMask_) ? 1 : 0
}
set diffValue(newValue: number) {
set diffValue(newValue: 0 | 1) {
this.flags_ = setFlag(this.flags_, Reaction.diffValueMask_, newValue === 1 ? true : false)
}

Expand Down
3 changes: 2 additions & 1 deletion packages/mobx/src/types/observablemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
hasListeners,
interceptChange,
isES6Map,
isPlainES6Map,
isPlainObject,
isSpyEnabled,
makeIterable,
Expand Down Expand Up @@ -351,7 +352,7 @@ export class ObservableMap<K = any, V = any>
} else if (Array.isArray(other)) {
other.forEach(([key, value]) => this.set(key, value))
} else if (isES6Map(other)) {
if (other.constructor !== Map) {
if (!isPlainES6Map(other)) {
die(19, other)
}
other.forEach((value, key) => this.set(key, value))
Expand Down
Loading

0 comments on commit c8b91d5

Please sign in to comment.