Skip to content

Commit

Permalink
feat(atom): re-import atom package from MBP2010, update main readme
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jan 28, 2018
1 parent bddd5ce commit fefc283
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Mono-repository for thi.ng TypeScript/ES6 projects.
| Projects | Version | |
|----|----|----|
| [`@thi.ng/api`](./packages/api) | [![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/api.svg)](https://www.npmjs.com/package/@thi.ng/api) | [changelog](./packages/api/CHANGELOG.md) |
| [`@thi.ng/atom`](./packages/atom) | [![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/atom.svg)](https://www.npmjs.com/package/@thi.ng/atom) | [changelog](./packages/atom/CHANGELOG.md) |
| [`@thi.ng/bitstream`](./packages/bitstream) | [![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/bitstream.svg)](https://www.npmjs.com/package/@thi.ng/bitstream) | [changelog](./packages/bitstream/CHANGELOG.md) |
| [`@thi.ng/checks`](./packages/checks) | [![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/checks.svg)](https://www.npmjs.com/package/@thi.ng/checks) | [changelog](./packages/checks/CHANGELOG.md) |
| [`@thi.ng/csp`](./packages/csp) | [![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/csp.svg)](https://www.npmjs.com/package/@thi.ng/csp) | [changelog](./packages/csp/CHANGELOG.md) |
Expand Down
11 changes: 11 additions & 0 deletions packages/atom/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/bench
/build
/dev
/doc
/node_modules
.DS_Store
/bundle.*
*.log
*.tgz
*.js
*.d.ts
14 changes: 14 additions & 0 deletions packages/atom/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
bench/*
build/*
dev/*
node_modules
src*
test*
bundle.*
tsconfig.json
webpack.config.js
*.html
*.tgz
!doc/*
!*.d.ts
!*.js
43 changes: 43 additions & 0 deletions packages/atom/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# @thi.ng/atom

[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/atom.svg)](https://www.npmjs.com/package/@thi.ng/atom)

## About

Clojure inspired mutable wrapper for (usually) immutable values, with support for watches.

## Installation

```
yarn add @thi.ng/atom
```

## Usage examples

```typescript
import { Atom } from "@thi.ng/atom";

const a = new Atom(23);

// obtain value via deref()
a.deref();
// 23

// add watch to observe value changes
a.addWatch("foo", (id, prev, curr) => console.log(`${id}: ${prev} -> ${curr}`));
// true

a.swap((val)=> val + 1);
// foo: 23 -> 24

a.reset(42);
// foo: 24 -> 42
```

## Authors

- Karsten Schmidt

## License

© 2018 Karsten Schmidt // Apache Software License 2.0
35 changes: 35 additions & 0 deletions packages/atom/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "@thi.ng/atom",
"version": "0.0.1",
"description": "Mutable wrapper for a immutable values",
"main": "./index.js",
"typings": "./index.d.ts",
"repository": "https://github.com/thi-ng/umbrella",
"author": "Karsten Schmidt <k+npm@thi.ng>",
"license": "Apache-2.0",
"scripts": {
"build": "yarn run clean && tsc --declaration",
"test": "yarn run clean && tsc -p test && mocha build/test/*.js",
"clean": "rm -rf *.js *.d.ts build doc",
"pub": "yarn run build && yarn publish --access public"
},
"devDependencies": {
"@types/mocha": "^2.2.46",
"@types/node": "^9.3.0",
"mocha": "^5.0.0",
"ts-loader": "^3.3.1",
"typedoc": "^0.9.0",
"typescript": "^2.6.2",
"webpack": "^3.10.0"
},
"dependencies": {
"@thi.ng/api": "^1.3.0"
},
"keywords": [
"ES6",
"typescript"
],
"publishConfig": {
"access": "public"
}
}
55 changes: 55 additions & 0 deletions packages/atom/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as api from "@thi.ng/api/api";
import { IWatch } from "@thi.ng/api/mixins/iwatch";

/**
* Mutable wrapper for an (usually) immutable value.
* Support for watches.
*/
@IWatch
export class Atom<T> implements
api.IDeref<T>,
api.IEquiv,
api.IWatch<T> {

protected value: T;

constructor(val?: T) {
this.value = val;
}

public deref() {
return this.value;
}

public equiv(o: any) {
return this === o;
}

public reset(val: T) {
const old = this.value;
this.value = val;
this.notifyWatches(old, val);
return this.value;
}

public swap(fn: (curr: T, ...args: any[]) => T, ...args: any[]) {
const old = this.value;
args.unshift(old);
this.value = fn.apply(null, args);
this.notifyWatches(old, this.value);
return this.value;
}

// mixin stub
public addWatch(id: string, fn: (id: string, oldState: T, newState: T) => void) {
return false;
}

// mixin stub
public removeWatch(id: string) {
return false;
}

// mixin stub
public notifyWatches(oldState: T, newState: T) { }
}
42 changes: 42 additions & 0 deletions packages/atom/test/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as assert from "assert";
import { Atom } from "../src/index";

describe("atom", function () {

let a: Atom<any>;

beforeEach(() => {
a = new Atom(23);
});

it("can be deref'd", () => {
assert.equal(a.deref(), 23);
});

it("can be reset", () => {
assert.equal(a.reset(24), 24);
assert.equal(a.deref(), 24);
});

it("can be swapped", () => {
assert.equal(a.swap((x) => x + 1), 24);
assert.equal(a.deref(), 24);
});

it("can add & remove watch", () => {
assert(a.addWatch("foo", () => { }), "can't add watch");
assert((<any>a)._watches && (<any>a)._watches.foo, "watch missing");
assert(a.removeWatch("foo"), "can't remove watch");
assert(!a.removeWatch("foo"), "should fail to remove invalid watch id");
});

it("can be watched", () => {
a.addWatch("foo", (id, prev, curr) => {
assert.equal(id, "foo", "wrong id");
assert.equal(prev, 23, "wrong prev");
assert.equal(curr, 24, "wrong curr");
});
a.swap((x) => x + 1);
});

});
11 changes: 11 additions & 0 deletions packages/atom/test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "../build",
"noUnusedParameters": false
},
"include": [
"./**/*.ts",
"../src/**/*.ts"
]
}
10 changes: 10 additions & 0 deletions packages/atom/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": ".",
"noUnusedParameters": false,
},
"include": [
"./src/**/*.ts",
]
}

0 comments on commit fefc283

Please sign in to comment.