@effectionx/chain 0.1.0

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/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Chain
2
+
3
+ There are some use-cases for Promise for which there is not a 1:1 analogue in
4
+ Effection. One of these is the "promise chaining" behavior of the `Promise`
5
+ constructor itself using `then()`, `catch()`, and `finally()`.
6
+
7
+ The chain package accomplishes this in a very similar way:
8
+
9
+ ```ts
10
+ import { Chain } from "@effectionx/chain";
11
+
12
+ await main(function* () {
13
+ let chain = new Chain<number>((resolve) => {
14
+ resolve(10);
15
+ });
16
+
17
+ let result = yield* chain.then(function* (value) {
18
+ return value * 2;
19
+ });
20
+
21
+ console.log(result); //=> 20;
22
+ });
23
+ ```
24
+
25
+ Another is to share a promise in multiple places. For example this async data
26
+ call is used and re-used:
27
+
28
+ ```ts
29
+ class Foo {
30
+ data: Promise<number>;
31
+
32
+ constructor() {
33
+ this.data = (async () => 5)();
34
+ }
35
+
36
+ async getData() {
37
+ return await this.data;
38
+ }
39
+ }
40
+
41
+ const foo = new Foo();
42
+ console.log(await foo.getData());
43
+ ```
44
+
45
+ This can be accomplished with Chain like so:
46
+
47
+ ```ts
48
+ class Foo {
49
+ data: Promise<number>;
50
+
51
+ constructor() {
52
+ let operation = (function* () {
53
+ return 5;
54
+ })();
55
+ this.data = Chain.from(operation);
56
+ }
57
+
58
+ *getData() {
59
+ return yield* this.data;
60
+ }
61
+ }
62
+
63
+ const foo = new Foo();
64
+ console.log(yield * foo.getData());
65
+ ```
66
+
67
+ ---
68
+
69
+ ```ts
70
+ import { Chain } from "@effectionx/chain";
71
+
72
+ await main(function* () {
73
+ let chain = new Chain<number>((resolve) => {
74
+ resolve(10);
75
+ });
76
+
77
+ let result = yield* chain.then(function* (value) {
78
+ return value * 2;
79
+ });
80
+
81
+ console.log(result); //=> 20;
82
+ });
83
+ ```
package/esm/mod.d.ts ADDED
@@ -0,0 +1,58 @@
1
+ import type { Operation, WithResolvers } from "effection";
2
+ /**
3
+ * Resolve a Chain
4
+ */
5
+ export type Resolve<T> = WithResolvers<T>["resolve"];
6
+ /**
7
+ * Reject a chain
8
+ */
9
+ export type Reject = WithResolvers<unknown>["reject"];
10
+ /**
11
+ * Represent the eventual completion of an [Operation] in a fashion
12
+ * that mirrors the * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promise}
13
+ * implementation
14
+ */
15
+ export declare class Chain<T> implements From<T> {
16
+ private resolvers;
17
+ /**
18
+ * Create a chain from any operation.
19
+ */
20
+ static from: typeof from;
21
+ constructor(compute: (resolve: Resolve<T>, reject: Reject) => void);
22
+ then<B>(fn: (value: T) => Operation<B>): From<B>;
23
+ catch<B>(fn: (error: unknown | Error) => Operation<B>): From<T | B>;
24
+ finally(fn: () => Operation<void>): From<T>;
25
+ [Symbol.iterator](): ReturnType<From<T>[typeof Symbol.iterator]>;
26
+ }
27
+ export interface From<A> extends Operation<A> {
28
+ /**
29
+ * Create a new chain that will resolve to the current chain's value after
30
+ * applying `fn`;
31
+ *
32
+ * @param `fn` - is applied to the source operation's result to create the chained operation's result
33
+ *
34
+ * @returns a new {Chain} representing this application
35
+ */
36
+ then<B>(fn: (value: A) => Operation<B>): From<B>;
37
+ /**
38
+ * Create a new chain that will resolve to the original chain's
39
+ * value, or the result of `fn` in the event that the current chain
40
+ * rejects. applying `fn`;
41
+ *
42
+ * @param `fn` - applied when the current chain rejects and becomes the result of chain
43
+ *
44
+ * @returns a new {Chain} representing the potentially caught rejection
45
+ */
46
+ catch<B>(fn: (error: unknown | Error) => Operation<B>): From<A | B>;
47
+ /**
48
+ * Create a new {Chain} that behaves exactly like the original chain, except that operation specified with
49
+ * `fn` will run in all cases.
50
+ *
51
+ * @param `fn` - a function returning an operation that is always
52
+ * evaluate just before the current chain yields its value.
53
+ */
54
+ finally(fn: () => Operation<void>): From<A>;
55
+ }
56
+ declare function from<T>(source: Operation<T>): From<T>;
57
+ export {};
58
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1D;;GAEG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;AAEtD;;;;GAIG;AACH,qBAAa,KAAK,CAAC,CAAC,CAAE,YAAW,IAAI,CAAC,CAAC,CAAC;IACtC,OAAO,CAAC,SAAS,CAAsB;IAEvC;;OAEG;IACH,MAAM,CAAC,IAAI,cAAQ;gBAEP,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI;IAKlE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAKhD,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAKnE,OAAO,CAAC,EAAE,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAK3C,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;CAGjE;AAED,MAAM,WAAW,IAAI,CAAC,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAC3C;;;;;;;OAOG;IACH,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAEjD;;;;;;;;OAQG;IACH,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAEpE;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;CAC7C;AAED,iBAAS,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAsC9C"}
package/esm/mod.js ADDED
@@ -0,0 +1,79 @@
1
+ import { call, withResolvers } from "effection";
2
+ /**
3
+ * Represent the eventual completion of an [Operation] in a fashion
4
+ * that mirrors the * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promise}
5
+ * implementation
6
+ */
7
+ export class Chain {
8
+ constructor(compute) {
9
+ Object.defineProperty(this, "resolvers", {
10
+ enumerable: true,
11
+ configurable: true,
12
+ writable: true,
13
+ value: withResolvers()
14
+ });
15
+ let { resolve, reject } = this.resolvers;
16
+ compute(resolve, reject);
17
+ }
18
+ then(fn) {
19
+ let { operation } = this.resolvers;
20
+ return from(operation).then(fn);
21
+ }
22
+ catch(fn) {
23
+ let { operation } = this.resolvers;
24
+ return from(operation).catch(fn);
25
+ }
26
+ finally(fn) {
27
+ let { operation } = this.resolvers;
28
+ return from(operation).finally(fn);
29
+ }
30
+ [Symbol.iterator]() {
31
+ return this.resolvers.operation[Symbol.iterator]();
32
+ }
33
+ }
34
+ /**
35
+ * Create a chain from any operation.
36
+ */
37
+ Object.defineProperty(Chain, "from", {
38
+ enumerable: true,
39
+ configurable: true,
40
+ writable: true,
41
+ value: from
42
+ });
43
+ function from(source) {
44
+ let resolvers = undefined;
45
+ let chain = {
46
+ *[Symbol.iterator]() {
47
+ if (!resolvers) {
48
+ resolvers = withResolvers();
49
+ try {
50
+ resolvers.resolve(yield* source);
51
+ }
52
+ catch (e) {
53
+ resolvers.reject(e);
54
+ }
55
+ }
56
+ return yield* resolvers.operation;
57
+ },
58
+ then: (fn) => from(call(function* () {
59
+ return yield* fn(yield* chain);
60
+ })),
61
+ catch: (fn) => from(call(function* () {
62
+ try {
63
+ return yield* chain;
64
+ }
65
+ catch (e) {
66
+ return yield* fn(e);
67
+ }
68
+ })),
69
+ finally: (fn) => from(call(function* () {
70
+ try {
71
+ return yield* chain;
72
+ }
73
+ finally {
74
+ yield* fn();
75
+ }
76
+ })),
77
+ };
78
+ return chain;
79
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@effectionx/chain",
3
+ "version": "0.1.0",
4
+ "author": "engineering@frontside.com",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/thefrontside/effectionx.git"
8
+ },
9
+ "license": "MIT",
10
+ "bugs": {
11
+ "url": "https://github.com/thefrontside/effectionx/issues"
12
+ },
13
+ "main": "./script/mod.js",
14
+ "module": "./esm/mod.js",
15
+ "exports": {
16
+ ".": {
17
+ "import": "./esm/mod.js",
18
+ "require": "./script/mod.js"
19
+ }
20
+ },
21
+ "scripts": {},
22
+ "engines": {
23
+ "node": ">= 16"
24
+ },
25
+ "sideEffects": false,
26
+ "dependencies": {
27
+ "effection": "^3 || ^4.0.0-0"
28
+ },
29
+ "_generatedBy": "dnt@dev"
30
+ }
@@ -0,0 +1,58 @@
1
+ import type { Operation, WithResolvers } from "effection";
2
+ /**
3
+ * Resolve a Chain
4
+ */
5
+ export type Resolve<T> = WithResolvers<T>["resolve"];
6
+ /**
7
+ * Reject a chain
8
+ */
9
+ export type Reject = WithResolvers<unknown>["reject"];
10
+ /**
11
+ * Represent the eventual completion of an [Operation] in a fashion
12
+ * that mirrors the * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promise}
13
+ * implementation
14
+ */
15
+ export declare class Chain<T> implements From<T> {
16
+ private resolvers;
17
+ /**
18
+ * Create a chain from any operation.
19
+ */
20
+ static from: typeof from;
21
+ constructor(compute: (resolve: Resolve<T>, reject: Reject) => void);
22
+ then<B>(fn: (value: T) => Operation<B>): From<B>;
23
+ catch<B>(fn: (error: unknown | Error) => Operation<B>): From<T | B>;
24
+ finally(fn: () => Operation<void>): From<T>;
25
+ [Symbol.iterator](): ReturnType<From<T>[typeof Symbol.iterator]>;
26
+ }
27
+ export interface From<A> extends Operation<A> {
28
+ /**
29
+ * Create a new chain that will resolve to the current chain's value after
30
+ * applying `fn`;
31
+ *
32
+ * @param `fn` - is applied to the source operation's result to create the chained operation's result
33
+ *
34
+ * @returns a new {Chain} representing this application
35
+ */
36
+ then<B>(fn: (value: A) => Operation<B>): From<B>;
37
+ /**
38
+ * Create a new chain that will resolve to the original chain's
39
+ * value, or the result of `fn` in the event that the current chain
40
+ * rejects. applying `fn`;
41
+ *
42
+ * @param `fn` - applied when the current chain rejects and becomes the result of chain
43
+ *
44
+ * @returns a new {Chain} representing the potentially caught rejection
45
+ */
46
+ catch<B>(fn: (error: unknown | Error) => Operation<B>): From<A | B>;
47
+ /**
48
+ * Create a new {Chain} that behaves exactly like the original chain, except that operation specified with
49
+ * `fn` will run in all cases.
50
+ *
51
+ * @param `fn` - a function returning an operation that is always
52
+ * evaluate just before the current chain yields its value.
53
+ */
54
+ finally(fn: () => Operation<void>): From<A>;
55
+ }
56
+ declare function from<T>(source: Operation<T>): From<T>;
57
+ export {};
58
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1D;;GAEG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;AAEtD;;;;GAIG;AACH,qBAAa,KAAK,CAAC,CAAC,CAAE,YAAW,IAAI,CAAC,CAAC,CAAC;IACtC,OAAO,CAAC,SAAS,CAAsB;IAEvC;;OAEG;IACH,MAAM,CAAC,IAAI,cAAQ;gBAEP,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI;IAKlE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAKhD,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAKnE,OAAO,CAAC,EAAE,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAK3C,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;CAGjE;AAED,MAAM,WAAW,IAAI,CAAC,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAC3C;;;;;;;OAOG;IACH,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAEjD;;;;;;;;OAQG;IACH,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAEpE;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;CAC7C;AAED,iBAAS,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAsC9C"}
package/script/mod.js ADDED
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Chain = void 0;
4
+ const effection_1 = require("effection");
5
+ /**
6
+ * Represent the eventual completion of an [Operation] in a fashion
7
+ * that mirrors the * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promise}
8
+ * implementation
9
+ */
10
+ class Chain {
11
+ constructor(compute) {
12
+ Object.defineProperty(this, "resolvers", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: (0, effection_1.withResolvers)()
17
+ });
18
+ let { resolve, reject } = this.resolvers;
19
+ compute(resolve, reject);
20
+ }
21
+ then(fn) {
22
+ let { operation } = this.resolvers;
23
+ return from(operation).then(fn);
24
+ }
25
+ catch(fn) {
26
+ let { operation } = this.resolvers;
27
+ return from(operation).catch(fn);
28
+ }
29
+ finally(fn) {
30
+ let { operation } = this.resolvers;
31
+ return from(operation).finally(fn);
32
+ }
33
+ [Symbol.iterator]() {
34
+ return this.resolvers.operation[Symbol.iterator]();
35
+ }
36
+ }
37
+ exports.Chain = Chain;
38
+ /**
39
+ * Create a chain from any operation.
40
+ */
41
+ Object.defineProperty(Chain, "from", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: from
46
+ });
47
+ function from(source) {
48
+ let resolvers = undefined;
49
+ let chain = {
50
+ *[Symbol.iterator]() {
51
+ if (!resolvers) {
52
+ resolvers = (0, effection_1.withResolvers)();
53
+ try {
54
+ resolvers.resolve(yield* source);
55
+ }
56
+ catch (e) {
57
+ resolvers.reject(e);
58
+ }
59
+ }
60
+ return yield* resolvers.operation;
61
+ },
62
+ then: (fn) => from((0, effection_1.call)(function* () {
63
+ return yield* fn(yield* chain);
64
+ })),
65
+ catch: (fn) => from((0, effection_1.call)(function* () {
66
+ try {
67
+ return yield* chain;
68
+ }
69
+ catch (e) {
70
+ return yield* fn(e);
71
+ }
72
+ })),
73
+ finally: (fn) => from((0, effection_1.call)(function* () {
74
+ try {
75
+ return yield* chain;
76
+ }
77
+ finally {
78
+ yield* fn();
79
+ }
80
+ })),
81
+ };
82
+ return chain;
83
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }