evg_observable 3.1.0 → 3.1.1
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/.claudeignore +9 -0
- package/package.json +19 -4
- package/repo/evg_observable.old.js +1 -0
- package/scripts/README.md +69 -0
- package/scripts/claude-full-check.sh +33 -0
- package/scripts/claude-pr-prep.sh +73 -0
- package/scripts/claude-review-files.sh +61 -0
- package/src/outLib/CoreTypes.d.ts +42 -0
- package/src/outLib/CoreTypes.js +2 -0
- package/src/outLib/FilterCollection.js +2 -1
- package/src/outLib/FilterTypes.d.ts +27 -0
- package/src/outLib/FilterTypes.js +2 -0
- package/src/outLib/Observable.d.ts +1 -1
- package/src/outLib/Observable.js +6 -6
- package/src/outLib/Pipe.js +2 -1
- package/src/outLib/PipeTypes.d.ts +77 -0
- package/src/outLib/PipeTypes.js +2 -0
- package/src/outLib/SubscribeObject.js +2 -2
- package/src/outLib/SubscriptionTypes.d.ts +40 -0
- package/src/outLib/SubscriptionTypes.js +2 -0
- package/src/outLib/Types.d.ts +4 -224
- package/src/outLib/Types.js +18 -0
- package/src/outLib-esm/index.mjs +1 -0
package/.claudeignore
ADDED
package/package.json
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "evg_observable",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "Lightweight reactive Observable library (zero dependencies) — 2-7x faster than RxJS, 1.5-3x faster than observable-fns. Pipe operators: throttle, debounce, distinctUntilChanged, map, tap. Original hot-observable architecture, not a fork or wrapper.",
|
|
5
|
-
"main": "src/outLib/index.js",
|
|
6
|
-
"
|
|
5
|
+
"main": "./src/outLib/index.js",
|
|
6
|
+
"module": "./src/outLib-esm/index.mjs",
|
|
7
|
+
"types": "./src/outLib/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./src/outLib/index.d.ts",
|
|
12
|
+
"default": "./src/outLib-esm/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./src/outLib/index.d.ts",
|
|
16
|
+
"default": "./src/outLib/index.js"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
7
20
|
"directories": {
|
|
8
21
|
"test": "test"
|
|
9
22
|
},
|
|
10
23
|
"scripts": {
|
|
11
24
|
"test": "nyc ./node_modules/.bin/_mocha 'test/**/*.test.ts'",
|
|
12
25
|
"remove": "rm -rf ./src/Libraries; rm -rf ./test; rm .mocharc.json; rm .nyrc.json; rm register.js; rm tsconfig.json",
|
|
13
|
-
"build": "tsc --declaration
|
|
26
|
+
"build": "tsc --declaration && npm run build:esm && npm run remove",
|
|
27
|
+
"build:esm": "esbuild src/Libraries/Observables/index.ts --bundle --format=esm --minify --outfile=src/outLib-esm/index.mjs",
|
|
14
28
|
"benchmark": "ts-node benchmarks/benchmark.ts",
|
|
15
29
|
"benchmark:comparison": "ts-node benchmarks/benchmark-comparison.ts",
|
|
16
30
|
"benchmark:competitors": "ts-node benchmarks/benchmark-competitors.ts",
|
|
17
31
|
"benchmark:browser": "ts-node benchmarks/benchmark-browser-bundle.ts",
|
|
32
|
+
"benchmark:esm": "ts-node benchmarks/benchmark-esm-bundle.ts",
|
|
18
33
|
"benchmark:bundles": "ts-node benchmarks/benchmark-bundles.ts",
|
|
19
34
|
"benchmark:patterns": "ts-node benchmarks/benchmark-subscription-patterns.ts",
|
|
20
35
|
"benchmark:patterns-edge": "ts-node benchmarks/benchmark-patterns-edge-cases.ts",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{"use strict";function s(s,r){return s.order>r.order?1:s.order<r.order?-1:0}function r(s,r){return s.order>r.order?-1:s.order<r.order?1:0}function e(s,r){const e=s.indexOf(r);return-1!==e&&(s.splice(e,1),!0)}function i(s){return"next"in s?r=>s.next(r):s}class t{pipe;counter;constructor(s){this.pipe=s,this.counter=s.chain.length?s.chain.length:0}or(s){this.counter++;const r=this.counter,e=this.pipe.chain;return e.push(i=>{i.isAvailable=!0,s(i.payload)&&(i.isBreak=!0),r!==e.length||i.isBreak||(i.isAvailable=!1)}),this}anyOf(s){if(!Array.isArray(s))return this;for(let r=0;r<s.length;r++)this.or(s[r]);return this}}class n{chain=[];flow={isBreak:!1,isUnsubscribe:!1,isAvailable:!1,payload:null};push(s){return this.chain.push(s),this}once(){return this.push(s=>{this.listener(s.payload),s.isUnsubscribe=!0})}unsubscribeBy(s){return this.push(r=>{r.isAvailable=!0,s(r.payload)&&(r.isUnsubscribe=!0)})}and(s){return this.push(r=>s(r.payload)&&(r.isAvailable=!0))}allOf(s){if(!Array.isArray(s))return this;for(let r=0;r<s.length;r++)this.and(s[r]);return this}choice(){return new h(this)}map(s){return this.push(r=>{r.payload=s(r.payload),r.isAvailable=!0})}toJson(){return this.push(s=>{s.payload=JSON.stringify(s.payload),s.isAvailable=!0})}fromJson(){return this.push(s=>{s.payload=JSON.parse(s.payload),s.isAvailable=!0})}group(){return this}processChain(s){const r=this.chain,e=this.flow,i=r.length;for(let s=0;s<i;s++){if(e.isUnsubscribe=!1,e.isAvailable=!1,r[s](e),e.isUnsubscribe)return this.unsubscribe();if(!e.isAvailable)return;if(e.isBreak)break}return s(e.payload)}}class h extends t{subscribe(s,r){return this.pipe.subscribe(s,r)}group(){return this.pipe}}class l extends n{observer;listener;errorHandler=(s,r)=>{console.log(`(Unit of SubscribeObject).send(${s}) ERROR:`,r)};_order=0;paused=!1;piped=!1;listeners;errorHandlers;constructor(s,r){super(),this.observer=s,this.piped=!!r}subscribe(s,r){return this.listener=function(s){if(Array.isArray(s)){const r=[];for(let e=0;e<s.length;e++)r.push(i(s[e]));return s=>{for(let e=0;e<r.length;e++)r[e](s)}}return i(s)}(s),r&&(this.errorHandler=r),this}add(s,r){if(this.listeners||(this.listeners=[],this.errorHandlers=[]),Array.isArray(s))for(let e=0;e<s.length;e++){this.listeners.push(s[e]);const i=r&&Array.isArray(r)?r[e]??this.errorHandler:r||this.errorHandler;this.errorHandlers.push(i)}else{this.listeners.push(s);const e=r&&!Array.isArray(r)?r:this.errorHandler;this.errorHandlers.push(e)}return this}unsubscribe(){this.observer&&(this.observer.unSubscribe(this),this.observer=null,this.listener=null,this.chain.length=0)}send(s){const r=this.listener,e=this.listeners&&this.listeners.length>0;if(r||e){if(this.observer&&!this.paused)if(this.piped)try{if(this.flow.payload=s,this.flow.isBreak=!1,r)this.processChain(r);else{const s=this.chain,r=this.flow,e=s.length;r.isAvailable=0===e;for(let i=0;i<e;i++){if(r.isUnsubscribe=!1,r.isAvailable=!1,s[i](r),r.isUnsubscribe)return void this.unsubscribe();if(!r.isAvailable)return;if(r.isBreak)break}}if(e){const s=this.flow.payload;for(let r=0;r<this.listeners.length;r++)try{this.listeners[r](s)}catch(e){this.errorHandlers[r](s,e)}}}catch(r){this.errorHandler(s,r)}else{if(r)try{r(s)}catch(r){this.errorHandler(s,r)}if(e)for(let r=0;r<this.listeners.length;r++)try{this.listeners[r](s)}catch(e){this.errorHandlers[r](s,e)}}}else this.unsubscribe()}resume(){this.paused=!1}pause(){this.paused=!0}get order(){return this._order}set order(s){this._order=s}}class a{chain=[];flow={isBreak:!1,isAvailable:!1,payload:null};response={isOK:!1,payload:void 0};errHandler;get isEmpty(){return!this.chain.length}push(s){return this.chain.push(s),this}and(s){return this.push(r=>s(r.payload)&&(r.isAvailable=!0))}allOf(s){if(!Array.isArray(s))return this;for(let r=0;r<s.length;r++)this.and(s[r]);return this}choice(){return new o(this)}processChain(s){const r=this.chain,e=this.flow,i=this.response;i.isOK=!1,i.payload=void 0,e.payload=s,e.isBreak=!1;try{const s=r.length;for(let t=0;t<s;t++){if(e.isAvailable=!1,r[t](e),!e.isAvailable)return i;if(e.isBreak)break}}catch(s){return this.errHandler?this.errHandler(s,"Filter.processChain ERROR:"):console.log("Filter.processChain ERROR:",s),i}return i.isOK=!0,i.payload=e.payload,i}addErrorHandler(s){this.errHandler=s}}class o extends t{}class u{subs=[];enabled=!0;killed=!1;process=!1;trash=[];filters=new a;_value;constructor(s){this._value=s}addFilter(s){return s&&this.filters.addErrorHandler(s),this.filters}disable(){this.enabled=!1}enable(){this.enabled=!0}get isEnable(){return this.enabled}next(s){if(this.killed)return;if(!this.enabled)return;if(!this.subs.length)return;if(!this.filters.isEmpty&&!this.filters.processChain(s).isOK)return;this.process=!0,this._value=s;const r=this.subs,e=r.length;for(let i=0;i<e;i++)r[i].send(s);this.process=!1,this.trash.length&&this.clearTrash()}of(s){if(!this.killed&&this.enabled)for(let r=0;r<s.length;r++)this.next(s[r])}in(s){if(!this.killed&&this.enabled)for(const r in s)Object.hasOwn(s,r)&&this.next([r,s[r]])}clearTrash(){const s=this.trash.length;for(let r=0;r<s;r++)this.unSubscribe(this.trash[r]);this.trash.length=0}unSubscribe(s){this.killed||(this.process&&s?this.trash.push(s):this.subs&&e(this.subs,s))}destroy(){if(!this.killed){if(this.killed=!0,!this.process)return this._value=null,void(this.subs.length=0);Promise.resolve().then(()=>{this._value=null,this.subs.length=0})}}unsubscribeAll(){if(!this.killed){if(this.process){const s=this.subs;for(let r=0;r<s.length;r++)this.trash.push(s[r]);return}this.subs.length=0}}getValue(){if(!this.killed)return this._value}size(){return this.killed?0:this.subs.length}subscribe(s,r){if(this.killed)return;if(!this.isListener(s))return;const e=new l(this,!1);return this.addObserver(e,s,r),e}addObserver(s,r,e){s.subscribe(r,e),this.subs.push(s)}isListener(s){return!this.killed&&!!s}pipe(){if(this.killed)return;const s=new l(this,!0);return this.subs.push(s),s}get isDestroyed(){return this.killed}}class d extends l{constructor(s,r){super(s,r)}get order(){return this._order}set order(s){!this.observer||this.observer&&this.observer.isDestroyed?this._order=void 0:(this._order=s,this.observer.sortByOrder())}subscribe(s,r){return super.subscribe(s,r),this}once(){return super.once()}}const c=window;c.Observable=u,c.Collector=class{arr=[];killed=!1;collect(...s){this.killed||this.arr.push(...s)}unsubscribe(s){this.killed||(s?.unsubscribe(),e(this.arr,s))}unsubscribeAll(){if(this.killed)return;const s=this.arr;for(let r=0;r<s.length;r++)s[r].unsubscribe();s.length=0}size(){return this.killed?0:this.arr.length}destroy(){this.unsubscribeAll(),this.arr.length=0,this.arr=0,this.killed=!0}get isDestroyed(){return this.killed}},c.OrderedObservable=class extends u{sortDirection=s;ascendingSort(){return this.sortDirection=s,this.sortByOrder()}descendingSort(){return this.sortDirection=r,this.sortByOrder()}sortByOrder(){return!this.killed&&(this.subs.sort(this.sortDirection),!0)}subscribe(s,r){if(!this.isListener(s))return;const e=new d(this,!1);return this.addObserver(e,s,r),e}pipe(){if(this.killed)return;const s=new d(this,!0);return this.subs.push(s),s}unSubscribe(s){this.killed||(this.process&&s?this.trash.push(s):this.subs&&e(this.subs,s))}}})();
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Automation Scripts
|
|
2
|
+
|
|
3
|
+
Scripts for automated code review and PR preparation using Claude Code in headless mode.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Claude Code CLI installed (`npm install -g @anthropic-ai/claude-code`)
|
|
8
|
+
- Authenticated Claude session (API key or OAuth)
|
|
9
|
+
- Git repository with at least one base branch (`dev`, `stage`, `main`, or `master`)
|
|
10
|
+
|
|
11
|
+
## Scripts
|
|
12
|
+
|
|
13
|
+
### claude-review-files.sh
|
|
14
|
+
|
|
15
|
+
Code review of current branch changes against a base branch.
|
|
16
|
+
|
|
17
|
+
**What it checks:**
|
|
18
|
+
- Correctness and edge cases
|
|
19
|
+
- TypeScript type safety
|
|
20
|
+
- Naming conventions (PascalCase, camelCase, `I` prefix, `$` suffix)
|
|
21
|
+
- Code style (2-space indent, JSDoc)
|
|
22
|
+
- Resource cleanup (destroy/unsubscribe)
|
|
23
|
+
- Regression risk
|
|
24
|
+
|
|
25
|
+
**When to use:** After finishing implementation, before creating a PR. Helps catch problems early.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
./scripts/claude-review-files.sh # auto-detect base branch
|
|
29
|
+
./scripts/claude-review-files.sh dev # review against dev
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
### claude-pr-prep.sh
|
|
35
|
+
|
|
36
|
+
Runs tests and generates a PR description from commit history and test results.
|
|
37
|
+
|
|
38
|
+
**What it does:**
|
|
39
|
+
1. Runs `npm test` and captures results
|
|
40
|
+
2. Collects commit log between current and base branch
|
|
41
|
+
3. Generates a structured PR description (Summary, Changes, Test plan)
|
|
42
|
+
|
|
43
|
+
**When to use:** When the branch is ready for PR and you need a description.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
./scripts/claude-pr-prep.sh # auto-detect base branch
|
|
47
|
+
./scripts/claude-pr-prep.sh dev # prepare PR against dev
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
### claude-full-check.sh
|
|
53
|
+
|
|
54
|
+
Full pre-PR pipeline: runs review first, then PR preparation.
|
|
55
|
+
|
|
56
|
+
**What it does:**
|
|
57
|
+
1. Runs `claude-review-files.sh` — review code for issues
|
|
58
|
+
2. Runs `claude-pr-prep.sh` — run tests and generate PR description
|
|
59
|
+
|
|
60
|
+
**When to use:** Complete quality check before creating a PR. One command instead of two.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
./scripts/claude-full-check.sh # auto-detect base branch
|
|
64
|
+
./scripts/claude-full-check.sh dev # full check against dev
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Base Branch Detection
|
|
68
|
+
|
|
69
|
+
All scripts auto-detect the base branch in this order: `dev` → `stage` → `main` → `master`. The first existing branch is used. You can override by passing the branch name as an argument.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# scripts/claude-full-check.sh
|
|
3
|
+
# Full pre-PR pipeline: review code, then prepare PR description.
|
|
4
|
+
# Runs claude-review-files.sh first, then claude-pr-prep.sh.
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# ./scripts/claude-full-check.sh # auto-detect base branch
|
|
8
|
+
# ./scripts/claude-full-check.sh dev # explicit base branch
|
|
9
|
+
|
|
10
|
+
set -e
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
13
|
+
BASE="${1:-}"
|
|
14
|
+
|
|
15
|
+
echo "========================================="
|
|
16
|
+
echo " Step 1/2: Code Review"
|
|
17
|
+
echo "========================================="
|
|
18
|
+
echo ""
|
|
19
|
+
|
|
20
|
+
"$SCRIPT_DIR/claude-review-files.sh" $BASE
|
|
21
|
+
|
|
22
|
+
echo ""
|
|
23
|
+
echo "========================================="
|
|
24
|
+
echo " Step 2/2: PR Preparation"
|
|
25
|
+
echo "========================================="
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
"$SCRIPT_DIR/claude-pr-prep.sh" $BASE
|
|
29
|
+
|
|
30
|
+
echo ""
|
|
31
|
+
echo "========================================="
|
|
32
|
+
echo " Done. Review the output above."
|
|
33
|
+
echo "========================================="
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# scripts/claude-pr-prep.sh
|
|
3
|
+
# Run tests and generate a PR description for the current branch.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./scripts/claude-pr-prep.sh # auto-detect base branch
|
|
7
|
+
# ./scripts/claude-pr-prep.sh dev # explicit base branch
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
# Determine base branch
|
|
12
|
+
if [ -n "$1" ]; then
|
|
13
|
+
BASE="$1"
|
|
14
|
+
else
|
|
15
|
+
for branch in dev stage main master; do
|
|
16
|
+
if git rev-parse --verify "$branch" >/dev/null 2>&1; then
|
|
17
|
+
BASE="$branch"
|
|
18
|
+
break
|
|
19
|
+
fi
|
|
20
|
+
done
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
if [ -z "$BASE" ]; then
|
|
24
|
+
echo "Error: no base branch found (tried: dev, stage, main, master)"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
CURRENT=$(git branch --show-current)
|
|
29
|
+
|
|
30
|
+
echo "Preparing branch '$CURRENT' for PR into '$BASE'..."
|
|
31
|
+
echo ""
|
|
32
|
+
|
|
33
|
+
# Run tests
|
|
34
|
+
echo "=== Running tests ==="
|
|
35
|
+
TEST_OUTPUT=$(npm test 2>&1) || true
|
|
36
|
+
echo "$TEST_OUTPUT" | tail -5
|
|
37
|
+
echo ""
|
|
38
|
+
|
|
39
|
+
# Get commit log
|
|
40
|
+
COMMITS=$(git log "$BASE".."$CURRENT" --oneline 2>/dev/null)
|
|
41
|
+
|
|
42
|
+
if [ -z "$COMMITS" ]; then
|
|
43
|
+
echo "No commits between '$CURRENT' and '$BASE'. Nothing to prepare."
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Generate PR description
|
|
48
|
+
echo "=== Generating PR description ==="
|
|
49
|
+
echo ""
|
|
50
|
+
|
|
51
|
+
claude -p "Generate a pull request description for the EVG Observable library.
|
|
52
|
+
|
|
53
|
+
Branch: $CURRENT -> $BASE
|
|
54
|
+
|
|
55
|
+
Commits:
|
|
56
|
+
$COMMITS
|
|
57
|
+
|
|
58
|
+
Test results (last 5 lines):
|
|
59
|
+
$(echo "$TEST_OUTPUT" | tail -5)
|
|
60
|
+
|
|
61
|
+
Write a PR description in this format:
|
|
62
|
+
## Summary
|
|
63
|
+
<2-4 bullet points describing what changed and why>
|
|
64
|
+
|
|
65
|
+
## Changes
|
|
66
|
+
<list of key changes grouped by category>
|
|
67
|
+
|
|
68
|
+
## Test plan
|
|
69
|
+
<what was tested, test results summary>
|
|
70
|
+
|
|
71
|
+
Be concise and specific to this library." \
|
|
72
|
+
--print \
|
|
73
|
+
--max-turns 3
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# scripts/claude-review-files.sh
|
|
3
|
+
# Review current branch changes against base branch using Claude headless mode.
|
|
4
|
+
# Checks: correctness, types, naming, resource cleanup, regression risk.
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# ./scripts/claude-review-files.sh # auto-detect base branch
|
|
8
|
+
# ./scripts/claude-review-files.sh dev # explicit base branch
|
|
9
|
+
|
|
10
|
+
set -e
|
|
11
|
+
|
|
12
|
+
# Determine base branch
|
|
13
|
+
if [ -n "$1" ]; then
|
|
14
|
+
BASE="$1"
|
|
15
|
+
else
|
|
16
|
+
for branch in dev stage main master; do
|
|
17
|
+
if git rev-parse --verify "$branch" >/dev/null 2>&1; then
|
|
18
|
+
BASE="$branch"
|
|
19
|
+
break
|
|
20
|
+
fi
|
|
21
|
+
done
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
if [ -z "$BASE" ]; then
|
|
25
|
+
echo "Error: no base branch found (tried: dev, stage, main, master)"
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
CURRENT=$(git branch --show-current)
|
|
30
|
+
DIFF=$(git diff "$BASE"..."$CURRENT" 2>/dev/null)
|
|
31
|
+
|
|
32
|
+
if [ -z "$DIFF" ]; then
|
|
33
|
+
echo "No changes between '$CURRENT' and '$BASE'. Nothing to review."
|
|
34
|
+
exit 0
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
echo "Reviewing branch '$CURRENT' against '$BASE'..."
|
|
38
|
+
echo ""
|
|
39
|
+
|
|
40
|
+
claude -p "You are reviewing a code diff for the EVG Observable library.
|
|
41
|
+
|
|
42
|
+
Base branch: $BASE
|
|
43
|
+
Current branch: $CURRENT
|
|
44
|
+
|
|
45
|
+
Here is the diff:
|
|
46
|
+
|
|
47
|
+
$DIFF
|
|
48
|
+
|
|
49
|
+
Review this diff. For each changed file evaluate:
|
|
50
|
+
- **Correctness**: Does the code do what it should?
|
|
51
|
+
- **Edge cases**: Boundary conditions handled? (null, undefined, empty arrays)
|
|
52
|
+
- **Type safety**: Proper TypeScript types, no unnecessary \`any\`
|
|
53
|
+
- **Naming**: PascalCase classes, camelCase methods, \`I\` prefix for interfaces, \`\$\` suffix for observables
|
|
54
|
+
- **Style**: 2-space indent, JSDoc on public methods
|
|
55
|
+
- **Resource cleanup**: Are subscriptions cleaned up? destroy()/unsubscribe() where needed?
|
|
56
|
+
- **Regression risk**: Could this break existing behavior?
|
|
57
|
+
|
|
58
|
+
Output a table of issues found with severity (critical/major/minor), file, line, and description.
|
|
59
|
+
If no issues found, say so. Be specific and concise." \
|
|
60
|
+
--print \
|
|
61
|
+
--max-turns 5
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type ICallback<T> = (value?: T) => any;
|
|
2
|
+
export type IErrorCallback = (errorData: any, errorMessage: any) => void;
|
|
3
|
+
export type IListener<T> = ICallback<T>;
|
|
4
|
+
export type IDestroy = {
|
|
5
|
+
destroy(): void;
|
|
6
|
+
isDestroyed: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type IOrder = {
|
|
9
|
+
order: number;
|
|
10
|
+
};
|
|
11
|
+
export type ISetObservableValue = {
|
|
12
|
+
next(value: any): void;
|
|
13
|
+
};
|
|
14
|
+
export type IPause = {
|
|
15
|
+
pause(): void;
|
|
16
|
+
resume(): void;
|
|
17
|
+
};
|
|
18
|
+
export type ISubscribeCounter = {
|
|
19
|
+
size(): number;
|
|
20
|
+
};
|
|
21
|
+
export type IStream<T> = {
|
|
22
|
+
of(value: T[]): void;
|
|
23
|
+
};
|
|
24
|
+
export type ISend<T> = {
|
|
25
|
+
send(value: T): void;
|
|
26
|
+
};
|
|
27
|
+
export type IChainContainer = {
|
|
28
|
+
chain: any[];
|
|
29
|
+
};
|
|
30
|
+
export type IPipePayload = {
|
|
31
|
+
isBreak: boolean;
|
|
32
|
+
isUnsubscribe: boolean;
|
|
33
|
+
isAvailable: boolean;
|
|
34
|
+
debounceMs: number;
|
|
35
|
+
debounceTimer: any;
|
|
36
|
+
debounceValue: any;
|
|
37
|
+
debounceIndex: number;
|
|
38
|
+
payload: any;
|
|
39
|
+
};
|
|
40
|
+
export type IChainCallback = (data: IPipePayload) => void;
|
|
41
|
+
export type ICombinedSubscriber<T> = IListener<T> | ISetObservableValue;
|
|
42
|
+
export type ISubscribeGroup<T> = ICombinedSubscriber<T> | ICombinedSubscriber<T>[];
|
|
@@ -15,7 +15,8 @@ class FilterCollection {
|
|
|
15
15
|
return this;
|
|
16
16
|
}
|
|
17
17
|
and(condition) {
|
|
18
|
-
return this.push((data) => condition(data.payload)
|
|
18
|
+
return this.push((data) => { if (condition(data.payload))
|
|
19
|
+
data.isAvailable = true; });
|
|
19
20
|
}
|
|
20
21
|
allOf(conditions) {
|
|
21
22
|
if (!Array.isArray(conditions))
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { FilterSwitchCase } from "./FilterCollection";
|
|
2
|
+
import { ICallback } from "./CoreTypes";
|
|
3
|
+
export type IFilterPayload = {
|
|
4
|
+
isBreak: boolean;
|
|
5
|
+
isAvailable: boolean;
|
|
6
|
+
payload: any;
|
|
7
|
+
};
|
|
8
|
+
export type IFilterChainCallback = (data: IFilterPayload) => void;
|
|
9
|
+
export type IFilterResponse = {
|
|
10
|
+
isOK: boolean;
|
|
11
|
+
payload: any;
|
|
12
|
+
};
|
|
13
|
+
export type IFilter<T> = {
|
|
14
|
+
and(condition: ICallback<any>): IFilterSetup<T>;
|
|
15
|
+
allOf(conditions: ICallback<any>[]): IFilterSetup<T>;
|
|
16
|
+
};
|
|
17
|
+
export type IFilterSetup<T> = IFilter<T> & IFilterSwitch<T>;
|
|
18
|
+
export type IFilterSwitch<T> = {
|
|
19
|
+
choice(): FilterSwitchCase<T>;
|
|
20
|
+
};
|
|
21
|
+
export type IFilterCase<T> = {
|
|
22
|
+
or(condition: ICallback<any>): IFilterCase<T>;
|
|
23
|
+
anyOf(conditions: ICallback<any>[]): IFilterCase<T>;
|
|
24
|
+
};
|
|
25
|
+
export type IAddFilter<T> = {
|
|
26
|
+
addFilter(): IFilterSetup<T>;
|
|
27
|
+
};
|
|
@@ -8,7 +8,7 @@ export declare class Observable<T> implements IObserver<T>, IStream<T>, IAddFilt
|
|
|
8
8
|
protected process: boolean;
|
|
9
9
|
protected trash: ISubscriptionLike[];
|
|
10
10
|
protected filters: FilterCollection<T>;
|
|
11
|
-
protected _value: T;
|
|
11
|
+
protected _value: T | null;
|
|
12
12
|
constructor(value: T);
|
|
13
13
|
addFilter(errorHandler?: IErrorCallback): IFilterSetup<T>;
|
|
14
14
|
disable(): void;
|
package/src/outLib/Observable.js
CHANGED
|
@@ -45,6 +45,12 @@ class Observable {
|
|
|
45
45
|
for (let i = 0; i < len; i++)
|
|
46
46
|
subs[i].send(value);
|
|
47
47
|
this.process = false;
|
|
48
|
+
if (this.killed) {
|
|
49
|
+
this.clearDebounceTimers();
|
|
50
|
+
this._value = null;
|
|
51
|
+
this.subs.length = 0;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
48
54
|
this.trash.length && this.clearTrash();
|
|
49
55
|
}
|
|
50
56
|
of(values) {
|
|
@@ -89,13 +95,7 @@ class Observable {
|
|
|
89
95
|
this.clearDebounceTimers();
|
|
90
96
|
this._value = null;
|
|
91
97
|
this.subs.length = 0;
|
|
92
|
-
return;
|
|
93
98
|
}
|
|
94
|
-
Promise.resolve().then(() => {
|
|
95
|
-
this.clearDebounceTimers();
|
|
96
|
-
this._value = null;
|
|
97
|
-
this.subs.length = 0;
|
|
98
|
-
});
|
|
99
99
|
}
|
|
100
100
|
unsubscribeAll() {
|
|
101
101
|
if (this.killed)
|
package/src/outLib/Pipe.js
CHANGED
|
@@ -59,7 +59,8 @@ class Pipe {
|
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
and(condition) {
|
|
62
|
-
return this.push((data) => condition(data.payload)
|
|
62
|
+
return this.push((data) => { if (condition(data.payload))
|
|
63
|
+
data.isAvailable = true; });
|
|
63
64
|
}
|
|
64
65
|
allOf(conditions) {
|
|
65
66
|
if (!Array.isArray(conditions))
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { PipeSwitchCase } from "./Pipe";
|
|
2
|
+
import { ICallback, IPause, IOrder, ISend } from "./CoreTypes";
|
|
3
|
+
import { ISubscribe, IOrderedSubscribe, ISubscriptionLike, IGroupSubscription } from "./SubscriptionTypes";
|
|
4
|
+
export type ISwitch<T> = {
|
|
5
|
+
choice(): PipeSwitchCase<T>;
|
|
6
|
+
};
|
|
7
|
+
export type IGroup<T> = {
|
|
8
|
+
group(): IGroupSubscription<T>;
|
|
9
|
+
};
|
|
10
|
+
export type IOrderedGroup<T> = {
|
|
11
|
+
group(): IGroupSubscription<T>;
|
|
12
|
+
};
|
|
13
|
+
export type IOnce<T> = {
|
|
14
|
+
once(): ISubscribe<T>;
|
|
15
|
+
};
|
|
16
|
+
export type IOrderedOnce<T> = {
|
|
17
|
+
once(): IOrderedSubscribe<T>;
|
|
18
|
+
};
|
|
19
|
+
export type ITake<T> = {
|
|
20
|
+
take(n: number): ISubscribe<T>;
|
|
21
|
+
};
|
|
22
|
+
export type IOrderedTake<T> = {
|
|
23
|
+
take(n: number): IOrderedSubscribe<T>;
|
|
24
|
+
};
|
|
25
|
+
export type ISkip<T> = {
|
|
26
|
+
skip(n: number): ISetup<T>;
|
|
27
|
+
};
|
|
28
|
+
export type IOrderedSkip<T> = {
|
|
29
|
+
skip(n: number): IOrderedSetup<T>;
|
|
30
|
+
};
|
|
31
|
+
export type IScan<T> = {
|
|
32
|
+
scan<K>(fn: (accumulator: K, value: T) => K, seed: K): ISetup<K>;
|
|
33
|
+
};
|
|
34
|
+
export type IOrderedScan<T> = {
|
|
35
|
+
scan<K>(fn: (accumulator: K, value: T) => K, seed: K): IOrderedSetup<K>;
|
|
36
|
+
};
|
|
37
|
+
export type IUnsubscribeByPositive<T> = {
|
|
38
|
+
unsubscribeBy(condition: ICallback<T>): ISetup<T>;
|
|
39
|
+
};
|
|
40
|
+
export type IOrderedUnsubscribeByPositive<T> = {
|
|
41
|
+
unsubscribeBy(condition: ICallback<T>): ISetup<T>;
|
|
42
|
+
};
|
|
43
|
+
export type IEmitByPositive<T> = {
|
|
44
|
+
and(condition: ICallback<T>): ISetup<T>;
|
|
45
|
+
allOf(conditions: ICallback<T>[]): ISetup<T>;
|
|
46
|
+
};
|
|
47
|
+
export type IOrderedEmitByPositive<T> = {
|
|
48
|
+
and(condition: ICallback<any>): ISetup<T>;
|
|
49
|
+
allOf(conditions: ICallback<any>[]): ISetup<T>;
|
|
50
|
+
};
|
|
51
|
+
export type ITransform<T> = {
|
|
52
|
+
map<K>(condition: ICallback<T>): ISetup<K>;
|
|
53
|
+
};
|
|
54
|
+
export type IThrottle<T> = {
|
|
55
|
+
throttle(ms: number): ISetup<T>;
|
|
56
|
+
};
|
|
57
|
+
export type IDebounce<T> = {
|
|
58
|
+
debounce(ms: number): ISetup<T>;
|
|
59
|
+
};
|
|
60
|
+
export type IDistinctUntilChanged<T> = {
|
|
61
|
+
distinctUntilChanged(comparator?: (previous: T, current: T) => boolean): ISetup<T>;
|
|
62
|
+
};
|
|
63
|
+
export type ITap<T> = {
|
|
64
|
+
tap(fn: ICallback<T>): ISetup<T>;
|
|
65
|
+
};
|
|
66
|
+
export type ISerialisation = {
|
|
67
|
+
toJson(): ISetup<string>;
|
|
68
|
+
fromJson<K>(): ISetup<K>;
|
|
69
|
+
};
|
|
70
|
+
export type ISetup<T> = IUnsubscribeByPositive<T> & IEmitByPositive<T> & IOnce<T> & ITake<T> & ISkip<T> & IScan<T> & ISwitch<T> & ITransform<T> & IThrottle<T> & IDebounce<T> & IDistinctUntilChanged<T> & ITap<T> & ISerialisation & IGroup<T> & ISubscribe<T>;
|
|
71
|
+
export type IOrderedSetup<T> = IOrderedUnsubscribeByPositive<T> & IOrderedEmitByPositive<T> & IOrderedOnce<T> & IOrderedTake<T> & IOrderedSkip<T> & IOrderedScan<T> & ISwitch<T> & ITransform<T> & IThrottle<T> & IDebounce<T> & IDistinctUntilChanged<T> & ITap<T> & ISerialisation & IOrderedGroup<T> & IOrderedSubscribe<T>;
|
|
72
|
+
export type ISubscribeObject<T> = ISubscriptionLike & IPause & IOrder & ISend<T> & ISetup<T>;
|
|
73
|
+
export type IPipeCase<T> = ISubscribe<T> & {
|
|
74
|
+
or(condition: ICallback<any>): IPipeCase<T> & ISubscribe<T>;
|
|
75
|
+
anyOf(conditions: ICallback<any>[]): IPipeCase<T> & ISubscribe<T>;
|
|
76
|
+
group(): IGroupSubscription<T>;
|
|
77
|
+
};
|
|
@@ -52,8 +52,8 @@ class SubscribeObject extends Pipe_1.Pipe {
|
|
|
52
52
|
return;
|
|
53
53
|
clearTimeout(this.flow.debounceTimer);
|
|
54
54
|
this.observer.unSubscribe(this);
|
|
55
|
-
this.observer =
|
|
56
|
-
this.listener =
|
|
55
|
+
this.observer = undefined;
|
|
56
|
+
this.listener = undefined;
|
|
57
57
|
this.chain.length = 0;
|
|
58
58
|
}
|
|
59
59
|
send(value) {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { IDestroy, IErrorCallback, IListener, IOrder, ISetObservableValue, ISubscribeCounter, ISubscribeGroup } from "./CoreTypes";
|
|
2
|
+
import type { ISetup } from "./PipeTypes";
|
|
3
|
+
export type ISubscriptionLike = {
|
|
4
|
+
unsubscribe(): void;
|
|
5
|
+
};
|
|
6
|
+
export type IGroupSubscription<T> = ISubscriptionLike & {
|
|
7
|
+
add(listener: IListener<T> | IListener<T>[], errorHandler?: IErrorCallback | IErrorCallback[]): IGroupSubscription<T>;
|
|
8
|
+
};
|
|
9
|
+
export type ISubscribe<T> = {
|
|
10
|
+
subscribe(listener: ISubscribeGroup<T>, errorHandler?: IErrorCallback): ISubscriptionLike | undefined;
|
|
11
|
+
};
|
|
12
|
+
export type IOrderedSubscribe<T> = {
|
|
13
|
+
subscribe(listener: IListener<T>, errorHandler?: IErrorCallback): IOrderedSubscriptionLike;
|
|
14
|
+
};
|
|
15
|
+
export type ISubscriber<T> = {
|
|
16
|
+
getValue(): T | undefined;
|
|
17
|
+
isEnable: boolean;
|
|
18
|
+
} & ISubscribe<T>;
|
|
19
|
+
export type IOrderedSubscriptionLike = (ISubscriptionLike & IOrder);
|
|
20
|
+
export type IObservablePipe<T> = {
|
|
21
|
+
pipe(): ISetup<T> | undefined;
|
|
22
|
+
};
|
|
23
|
+
export type IOrderedObservablePipe<T> = {
|
|
24
|
+
pipe(): ISetup<T> | undefined;
|
|
25
|
+
};
|
|
26
|
+
export type IObserver<T> = ISetObservableValue & ISubscriber<T> & IDestroy & ISubscribeCounter & IObservablePipe<T> & {
|
|
27
|
+
unSubscribe(subscriber: ISubscriptionLike): void;
|
|
28
|
+
unsubscribeAll(): void;
|
|
29
|
+
disable(): void;
|
|
30
|
+
enable(): void;
|
|
31
|
+
};
|
|
32
|
+
export type IOrderedObservable = {
|
|
33
|
+
sortByOrder(): boolean;
|
|
34
|
+
};
|
|
35
|
+
export type IOrdered<T> = IObserver<T> & IOrderedObservable & IOrderedObservablePipe<T>;
|
|
36
|
+
export type ICollector = IDestroy & ISubscribeCounter & {
|
|
37
|
+
collect(...subscriptionLikeList: ISubscriptionLike[]): void;
|
|
38
|
+
unsubscribe(subscriptionLike: ISubscriptionLike): void;
|
|
39
|
+
unsubscribeAll(): void;
|
|
40
|
+
};
|
package/src/outLib/Types.d.ts
CHANGED
|
@@ -1,224 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export type ISubscribe<T> = {
|
|
6
|
-
subscribe(listener: ISubscribeGroup<T>, errorHandler?: IErrorCallback): ISubscriptionLike | undefined;
|
|
7
|
-
};
|
|
8
|
-
export type IListener<T> = ICallback<T>;
|
|
9
|
-
export type IDestroy = {
|
|
10
|
-
destroy(): void;
|
|
11
|
-
isDestroyed: boolean;
|
|
12
|
-
};
|
|
13
|
-
export type IOrder = {
|
|
14
|
-
order: number;
|
|
15
|
-
};
|
|
16
|
-
export type ISwitch<T> = {
|
|
17
|
-
choice(): PipeSwitchCase<T>;
|
|
18
|
-
};
|
|
19
|
-
export type IOrderedSwitch<T> = {
|
|
20
|
-
choice(): PipeSwitchCase<T>;
|
|
21
|
-
};
|
|
22
|
-
export type IGroup<T> = {
|
|
23
|
-
group(): IGroupSubscription<T>;
|
|
24
|
-
};
|
|
25
|
-
export type IOrderedGroup<T> = {
|
|
26
|
-
group(): IGroupSubscription<T>;
|
|
27
|
-
};
|
|
28
|
-
export type IOnce<T> = {
|
|
29
|
-
once(): ISubscribe<T>;
|
|
30
|
-
};
|
|
31
|
-
export type IOrderedOnce<T> = {
|
|
32
|
-
once(): IOrderedSubscribe<T>;
|
|
33
|
-
};
|
|
34
|
-
export type ITake<T> = {
|
|
35
|
-
take(n: number): ISubscribe<T>;
|
|
36
|
-
};
|
|
37
|
-
export type IOrderedTake<T> = {
|
|
38
|
-
take(n: number): IOrderedSubscribe<T>;
|
|
39
|
-
};
|
|
40
|
-
export type ISkip<T> = {
|
|
41
|
-
skip(n: number): ISetup<T>;
|
|
42
|
-
};
|
|
43
|
-
export type IOrderedSkip<T> = {
|
|
44
|
-
skip(n: number): IOrderedSetup<T>;
|
|
45
|
-
};
|
|
46
|
-
export type IScan<T> = {
|
|
47
|
-
scan<K>(fn: (accumulator: K, value: T) => K, seed: K): ISetup<K>;
|
|
48
|
-
};
|
|
49
|
-
export type IOrderedScan<T> = {
|
|
50
|
-
scan<K>(fn: (accumulator: K, value: T) => K, seed: K): IOrderedSetup<K>;
|
|
51
|
-
};
|
|
52
|
-
export type ISetObservableValue = {
|
|
53
|
-
next(value: any): void;
|
|
54
|
-
};
|
|
55
|
-
export type ISubscriptionLike = {
|
|
56
|
-
unsubscribe(): void;
|
|
57
|
-
};
|
|
58
|
-
export type IGroupSubscription<T> = ISubscriptionLike & {
|
|
59
|
-
add(listener: IListener<T> | IListener<T>[], errorHandler?: IErrorCallback | IErrorCallback[]): IGroupSubscription<T>;
|
|
60
|
-
};
|
|
61
|
-
export type ISetup<T> = IUnsubscribeByPositive<T> & IEmitByPositive<T> & IOnce<T> & ITake<T> & ISkip<T> & IScan<T> & ISwitch<T> & ITransform<T> & IThrottle<T> & IDebounce<T> & IDistinctUntilChanged<T> & ITap<T> & ISerialisation & IGroup<T> & ISubscribe<T>;
|
|
62
|
-
export type IOrderedSetup<T> = IOrderedUnsubscribeByPositive<T> & IOrderedEmitByPositive<T> & IOrderedOnce<T> & IOrderedTake<T> & IOrderedSkip<T> & IOrderedScan<T> & IOrderedSwitch<T> & IOrderedTransform<T> & IOrderedThrottle<T> & IOrderedDebounce<T> & IOrderedDistinctUntilChanged<T> & IOrderedTap<T> & IOrderedSerialisation & IOrderedGroup<T> & IOrderedSubscribe<T>;
|
|
63
|
-
export type ISubscribeObject<T> = ISubscriptionLike & IPause & IOrder & ISend<T> & ISetup<T>;
|
|
64
|
-
export type ISubscribeCounter = {
|
|
65
|
-
size(): number;
|
|
66
|
-
};
|
|
67
|
-
export type ISubscriber<T> = {
|
|
68
|
-
getValue(): T | undefined;
|
|
69
|
-
isEnable: boolean;
|
|
70
|
-
} & ISubscribe<T>;
|
|
71
|
-
export type IObserver<T> = ISetObservableValue & ISubscriber<T> & IDestroy & ISubscribeCounter & IObservablePipe<T> & {
|
|
72
|
-
unSubscribe(subscriber: ISubscriptionLike): void;
|
|
73
|
-
unsubscribeAll(): void;
|
|
74
|
-
disable(): void;
|
|
75
|
-
enable(): void;
|
|
76
|
-
};
|
|
77
|
-
export type IStream<T> = {
|
|
78
|
-
of(value: T[]): void;
|
|
79
|
-
};
|
|
80
|
-
export type IObjectStream<K extends string | number | symbol, V> = {
|
|
81
|
-
in(value: Record<K, V>): void;
|
|
82
|
-
};
|
|
83
|
-
export type IPause = {
|
|
84
|
-
pause(): void;
|
|
85
|
-
resume(): void;
|
|
86
|
-
};
|
|
87
|
-
export type IObservablePipe<T> = {
|
|
88
|
-
pipe(): ISetup<T> | undefined;
|
|
89
|
-
};
|
|
90
|
-
export type IOrderedObservablePipe<T> = {
|
|
91
|
-
pipe(): ISetup<T> | undefined;
|
|
92
|
-
};
|
|
93
|
-
export type ISend<T> = {
|
|
94
|
-
send(value: T): void;
|
|
95
|
-
};
|
|
96
|
-
export type IUnsubscribeByNegative<T> = {
|
|
97
|
-
unsubscribeByNegative(condition: ICallback<T>): ISetup<T>;
|
|
98
|
-
};
|
|
99
|
-
export type IOrderedUnsubscribeByNegative<T> = {
|
|
100
|
-
unsubscribeByNegative(condition: ICallback<T>): IOrderedSetup<T>;
|
|
101
|
-
};
|
|
102
|
-
export type IUnsubscribeByPositive<T> = {
|
|
103
|
-
unsubscribeBy(condition: ICallback<T>): ISetup<T>;
|
|
104
|
-
};
|
|
105
|
-
export type IOrderedUnsubscribeByPositive<T> = {
|
|
106
|
-
unsubscribeBy(condition: ICallback<T>): ISetup<T>;
|
|
107
|
-
};
|
|
108
|
-
export type IEmitByNegative<T> = {
|
|
109
|
-
emitByNegative(condition: ICallback<T>): ISetup<T>;
|
|
110
|
-
};
|
|
111
|
-
export type IOrderedEmitByNegative<T> = {
|
|
112
|
-
emitByNegative(condition: ICallback<T>): IOrderedSetup<T>;
|
|
113
|
-
};
|
|
114
|
-
export type IEmitByPositive<T> = {
|
|
115
|
-
and(condition: ICallback<T>): ISetup<T>;
|
|
116
|
-
allOf(conditions: ICallback<T>[]): ISetup<T>;
|
|
117
|
-
};
|
|
118
|
-
export type ITransform<T> = {
|
|
119
|
-
map<K>(condition: ICallback<T>): ISetup<K>;
|
|
120
|
-
};
|
|
121
|
-
export type IThrottle<T> = {
|
|
122
|
-
throttle(ms: number): ISetup<T>;
|
|
123
|
-
};
|
|
124
|
-
export type ISerialisation = {
|
|
125
|
-
toJson(): ISetup<string>;
|
|
126
|
-
fromJson<K>(): ISetup<K>;
|
|
127
|
-
};
|
|
128
|
-
export type IOrderedEmitByPositive<T> = {
|
|
129
|
-
and(condition: ICallback<any>): ISetup<T>;
|
|
130
|
-
allOf(conditions: ICallback<any>[]): ISetup<T>;
|
|
131
|
-
};
|
|
132
|
-
export type IOrderedTransform<T> = {
|
|
133
|
-
map<K>(condition: ICallback<T>): ISetup<K>;
|
|
134
|
-
};
|
|
135
|
-
export type IOrderedThrottle<T> = {
|
|
136
|
-
throttle(ms: number): ISetup<T>;
|
|
137
|
-
};
|
|
138
|
-
export type IDebounce<T> = {
|
|
139
|
-
debounce(ms: number): ISetup<T>;
|
|
140
|
-
};
|
|
141
|
-
export type IOrderedDebounce<T> = {
|
|
142
|
-
debounce(ms: number): ISetup<T>;
|
|
143
|
-
};
|
|
144
|
-
export type IDistinctUntilChanged<T> = {
|
|
145
|
-
distinctUntilChanged(comparator?: (previous: T, current: T) => boolean): ISetup<T>;
|
|
146
|
-
};
|
|
147
|
-
export type IOrderedDistinctUntilChanged<T> = {
|
|
148
|
-
distinctUntilChanged(comparator?: (previous: T, current: T) => boolean): ISetup<T>;
|
|
149
|
-
};
|
|
150
|
-
export type ITap<T> = {
|
|
151
|
-
tap(fn: ICallback<T>): ISetup<T>;
|
|
152
|
-
};
|
|
153
|
-
export type IOrderedTap<T> = {
|
|
154
|
-
tap(fn: ICallback<T>): ISetup<T>;
|
|
155
|
-
};
|
|
156
|
-
export type IOrderedSerialisation = {
|
|
157
|
-
toJson(): ISetup<string>;
|
|
158
|
-
fromJson<K>(): ISetup<K>;
|
|
159
|
-
};
|
|
160
|
-
export type IEmitMatchCondition<T> = {
|
|
161
|
-
emitMatch(condition: ICallback<any>): ISetup<T>;
|
|
162
|
-
};
|
|
163
|
-
export type IOrderedEmitMatchCondition<T> = {
|
|
164
|
-
emitMatch(condition: ICallback<any>): IOrderedSetup<T>;
|
|
165
|
-
};
|
|
166
|
-
export type ICollector = IDestroy & ISubscribeCounter & {
|
|
167
|
-
collect(...subscriptionLikeList: ISubscriptionLike[]): void;
|
|
168
|
-
unsubscribe(subscriptionLike: ISubscriptionLike): void;
|
|
169
|
-
unsubscribeAll(): void;
|
|
170
|
-
};
|
|
171
|
-
export type IOrderedObservable = {
|
|
172
|
-
sortByOrder(): boolean;
|
|
173
|
-
};
|
|
174
|
-
export type IOrdered<T> = IObserver<T> & IOrderedObservable & IOrderedObservablePipe<T>;
|
|
175
|
-
export type IOrderedSubscriptionLike = (ISubscriptionLike & IOrder);
|
|
176
|
-
export type IOrderedSubscribe<T> = {
|
|
177
|
-
subscribe(listener: IListener<T>, errorHandler?: IErrorCallback): IOrderedSubscriptionLike;
|
|
178
|
-
};
|
|
179
|
-
export type IChainContainer = {
|
|
180
|
-
chain: any[];
|
|
181
|
-
};
|
|
182
|
-
export type IPipePayload = {
|
|
183
|
-
isBreak: boolean;
|
|
184
|
-
isUnsubscribe: boolean;
|
|
185
|
-
isAvailable: boolean;
|
|
186
|
-
debounceMs: number;
|
|
187
|
-
debounceTimer: any;
|
|
188
|
-
debounceValue: any;
|
|
189
|
-
debounceIndex: number;
|
|
190
|
-
payload: any;
|
|
191
|
-
};
|
|
192
|
-
export type IChainCallback = (data: IPipePayload) => void;
|
|
193
|
-
export type IPipeCase<T> = ISubscribe<T> & {
|
|
194
|
-
or(condition: ICallback<any>): IPipeCase<T> & ISubscribe<T>;
|
|
195
|
-
anyOf(conditions: ICallback<any>[]): IPipeCase<T> & ISubscribe<T>;
|
|
196
|
-
group(): IGroupSubscription<T>;
|
|
197
|
-
};
|
|
198
|
-
export type ICombinedSubscriber<T> = IListener<T> | ISetObservableValue;
|
|
199
|
-
export type ISubscribeGroup<T> = ICombinedSubscriber<T> | ICombinedSubscriber<T>[];
|
|
200
|
-
export type IAddFilter<T> = {
|
|
201
|
-
addFilter(): IFilterSetup<T>;
|
|
202
|
-
};
|
|
203
|
-
export type IFilterSetup<T> = IFilter<T> & IFilterSwitch<T>;
|
|
204
|
-
export type IFilter<T> = {
|
|
205
|
-
and(condition: ICallback<any>): IFilterSetup<T>;
|
|
206
|
-
allOf(conditions: ICallback<any>[]): IFilterSetup<T>;
|
|
207
|
-
};
|
|
208
|
-
export type IFilterSwitch<T> = {
|
|
209
|
-
choice(): FilterSwitchCase<T>;
|
|
210
|
-
};
|
|
211
|
-
export type IFilterCase<T> = {
|
|
212
|
-
or(condition: ICallback<any>): IFilterCase<T>;
|
|
213
|
-
anyOf(conditions: ICallback<any>[]): IFilterCase<T>;
|
|
214
|
-
};
|
|
215
|
-
export type IFilterPayload = {
|
|
216
|
-
isBreak: boolean;
|
|
217
|
-
isAvailable: boolean;
|
|
218
|
-
payload: any;
|
|
219
|
-
};
|
|
220
|
-
export type IFilterChainCallback = (data: IFilterPayload) => void;
|
|
221
|
-
export type IFilterResponse = {
|
|
222
|
-
isOK: boolean;
|
|
223
|
-
payload: any;
|
|
224
|
-
};
|
|
1
|
+
export * from './CoreTypes';
|
|
2
|
+
export * from './SubscriptionTypes';
|
|
3
|
+
export * from './PipeTypes';
|
|
4
|
+
export * from './FilterTypes';
|
package/src/outLib/Types.js
CHANGED
|
@@ -1,2 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./CoreTypes"), exports);
|
|
18
|
+
__exportStar(require("./SubscriptionTypes"), exports);
|
|
19
|
+
__exportStar(require("./PipeTypes"), exports);
|
|
20
|
+
__exportStar(require("./FilterTypes"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function I(t,e){return t.order>e.order?1:t.order<e.order?-1:0}function k(t,e){return t.order>e.order?-1:t.order<e.order?1:0}function u(t,e){let r=t.indexOf(e);return r===-1?!1:(t.splice(r,1),!0)}function C(t,e){let r=t.indexOf(e);return r===-1?!1:(t[r]=t[t.length-1],t.length--,!0)}function v(t){if(Array.isArray(t)){let e=t.length,r=new Array(e);for(let i=0;i<e;i++)r[i]=S(t[i]);return i=>{for(let s=0;s<e;s++)r[s](i)}}return S(t)}function S(t){return"next"in t?e=>t.next(e):t}var b=class{pipe;counter;constructor(e){this.pipe=e,this.counter=e.chain.length?e.chain.length:0}or(e){this.counter++;let r=this.counter,i=this.pipe.chain;return i.push(s=>{s.isAvailable=!0,e(s.payload)&&(s.isBreak=!0),r===i.length&&!s.isBreak&&(s.isAvailable=!1)}),this}anyOf(e){if(!Array.isArray(e))return this;for(let r=0;r<e.length;r++)this.or(e[r]);return this}};var h=class{chain=[];flow={isBreak:!1,isUnsubscribe:!1,isAvailable:!1,debounceMs:0,debounceTimer:0,debounceValue:void 0,debounceIndex:0,payload:null};push(e){return this.chain.push(e),this}once(){return this.push(e=>{this.listener(e.payload),e.isUnsubscribe=!0})}take(e){e<0&&(e=0);let r=0;return this.push(i=>{if(r>=e){i.isUnsubscribe=!0;return}r++,this.listener(i.payload),r>=e&&(i.isUnsubscribe=!0)})}skip(e){e<0&&(e=0);let r=0;return this.push(i=>{if(r<e){r++;return}i.isAvailable=!0})}unsubscribeBy(e){return this.push(r=>{r.isAvailable=!0,e(r.payload)&&(r.isUnsubscribe=!0)})}and(e){return this.push(r=>{e(r.payload)&&(r.isAvailable=!0)})}allOf(e){if(!Array.isArray(e))return this;for(let r=0;r<e.length;r++)this.and(e[r]);return this}choice(){return new f(this)}map(e){return this.push(r=>{r.payload=e(r.payload),r.isAvailable=!0})}scan(e,r){let i=r;return this.push(s=>{i=e(i,s.payload),s.payload=i,s.isAvailable=!0})}tap(e){return this.push(r=>{e(r.payload),r.isAvailable=!0})}throttle(e){let r=0;return this.push(i=>{let s=Date.now();s-r>=e&&(r=s,i.isAvailable=!0)})}debounce(e){return this.push(r=>{r.isAvailable=!0,r.debounceMs=e})}distinctUntilChanged(e){let r=!1,i;return this.push(s=>{let n=s.payload;r&&(e?e(i,n):i===n)||(r=!0,i=n,s.isAvailable=!0)})}toJson(){return this.push(e=>{e.payload=JSON.stringify(e.payload),e.isAvailable=!0})}fromJson(){return this.push(e=>{e.payload=JSON.parse(e.payload),e.isAvailable=!0})}group(){return this}processChain(e){let r=this.chain,i=this.flow,s=r.length;for(let n=0;n<s;n++){if(i.isUnsubscribe=!1,i.isAvailable=!1,i.debounceMs=0,r[n](i),i.isUnsubscribe)return this.unsubscribe();if(i.debounceMs>0){i.debounceValue=i.payload,i.debounceIndex=n+1;let l=()=>{i.debounceTimer=0,i.payload=i.debounceValue,i.isBreak=!1;for(let a=i.debounceIndex;a<s;a++){if(i.isUnsubscribe=!1,i.isAvailable=!1,i.debounceMs=0,r[a](i),i.isUnsubscribe)return this.unsubscribe();if(i.debounceMs>0){i.debounceValue=i.payload,i.debounceIndex=a+1,clearTimeout(i.debounceTimer),i.debounceTimer=setTimeout(l,i.debounceMs);return}if(!i.isAvailable)return;if(i.isBreak)break}e&&e(i.payload)};clearTimeout(i.debounceTimer),i.debounceTimer=setTimeout(l,i.debounceMs);return}if(!i.isAvailable)return;if(i.isBreak)break}i.isAvailable=!0,e&&e(i.payload)}},f=class extends b{subscribe(e,r){return this.pipe.subscribe(e,r)}group(){return this.pipe}};var o=class extends h{observer;listener;errorHandler=(e,r)=>{console.log(`(Unit of SubscribeObject).send(${e}) ERROR:`,r)};_order=0;paused=!1;piped=!1;listeners;errorHandlers;constructor(e,r){super(),this.observer=e,this.piped=!!r}subscribe(e,r){return this.listener=v(e),r&&(this.errorHandler=r),this}add(e,r){if(this.listeners||(this.listeners=[],this.errorHandlers=[]),Array.isArray(e))for(let i=0;i<e.length;i++){this.listeners.push(e[i]);let s=r&&Array.isArray(r)?r[i]??this.errorHandler:r||this.errorHandler;this.errorHandlers.push(s)}else{this.listeners.push(e);let i=r&&!Array.isArray(r)?r:this.errorHandler;this.errorHandlers.push(i)}return this}unsubscribe(){this.observer&&(clearTimeout(this.flow.debounceTimer),this.observer.unSubscribe(this),this.observer=void 0,this.listener=void 0,this.chain.length=0)}send(e){let r=this.listener,i=this.listeners&&this.listeners.length>0;if(!r&&!i){this.unsubscribe();return}if(!(!this.observer||this.paused)){if(!this.piped){if(r)try{r(e)}catch(s){this.errorHandler(e,s)}return}try{if(this.flow.payload=e,this.flow.isBreak=!1,i){let s=this.listeners,n=this.errorHandlers;this.processChain(l=>{r&&r(l);for(let a=0;a<s.length;a++)try{s[a](l)}catch(O){n[a](l,O)}})}else this.processChain(r)}catch(s){this.errorHandler(e,s)}}}resume(){this.paused=!1}pause(){this.paused=!0}get order(){return this._order}set order(e){this._order=e}};var p=class{chain=[];flow={isBreak:!1,isAvailable:!1,payload:null};response={isOK:!1,payload:void 0};errHandler;get isEmpty(){return!this.chain.length}push(e){return this.chain.push(e),this}and(e){return this.push(r=>{e(r.payload)&&(r.isAvailable=!0)})}allOf(e){if(!Array.isArray(e))return this;for(let r=0;r<e.length;r++)this.and(e[r]);return this}choice(){return new T(this)}processChain(e){let r=this.chain,i=this.flow,s=this.response;s.isOK=!1,s.payload=void 0,i.payload=e,i.isBreak=!1;try{let n=r.length;for(let l=0;l<n;l++){if(i.isAvailable=!1,r[l](i),!i.isAvailable)return s;if(i.isBreak)break}}catch(n){return this.errHandler?this.errHandler(n,"Filter.processChain ERROR:"):console.log("Filter.processChain ERROR:",n),s}return s.isOK=!0,s.payload=i.payload,s}addErrorHandler(e){this.errHandler=e}},T=class extends b{};var c=class{subs=[];enabled=!0;killed=!1;process=!1;trash=[];filters=new p;_value;constructor(e){this._value=e}addFilter(e){return e&&this.filters.addErrorHandler(e),this.filters}disable(){this.enabled=!1}enable(){this.enabled=!0}get isEnable(){return this.enabled}next(e){if(this.killed||!this.enabled||!this.subs.length||!this.filters.isEmpty&&!this.filters.processChain(e).isOK)return;this.process=!0,this._value=e;let r=this.subs,i=r.length;for(let s=0;s<i;s++)r[s].send(e);if(this.process=!1,this.killed){this.clearDebounceTimers(),this._value=null,this.subs.length=0;return}this.trash.length&&this.clearTrash()}of(e){if(!this.killed&&this.enabled)for(let r=0;r<e.length;r++)this.next(e[r])}in(e){if(!this.killed&&this.enabled)for(let r in e)Object.hasOwn(e,r)&&this.next([r,e[r]])}clearTrash(){let e=this.trash.length;for(let r=0;r<e;r++)this.unSubscribe(this.trash[r]);this.trash.length=0}unSubscribe(e){if(!this.killed){if(this.process&&e){this.trash.push(e);return}this.subs&&u(this.subs,e)}}destroy(){this.killed||(this.killed=!0,this.process||(this.clearDebounceTimers(),this._value=null,this.subs.length=0))}unsubscribeAll(){if(!this.killed){if(this.process){this.clearDebounceTimers();let e=this.subs;for(let r=0;r<e.length;r++)this.trash.push(e[r]);return}this.clearDebounceTimers(),this.subs.length=0}}clearDebounceTimers(){let e=this.subs;for(let r=0;r<e.length;r++)clearTimeout(e[r].flow.debounceTimer)}getValue(){if(!this.killed)return this._value}size(){return this.killed?0:this.subs.length}subscribe(e,r){if(this.killed||!this.isListener(e))return;let i=new o(this,!1);return this.addObserver(i,e,r),i}addObserver(e,r,i){e.subscribe(r,i),this.subs.push(e)}isListener(e){return this.killed?!1:!!e}pipe(){if(this.killed)return;let e=new o(this,!0);return this.subs.push(e),e}get isDestroyed(){return this.killed}};var d=class extends o{constructor(e,r){super(e,r)}get order(){return this._order}set order(e){if(!this.observer||this.observer&&this.observer.isDestroyed){this._order=void 0;return}this._order=e,this.observer.sortByOrder()}subscribe(e,r){return super.subscribe(e,r),this}once(){return super.once()}take(e){return super.take(e)}skip(e){return super.skip(e)}scan(e,r){return super.scan(e,r)}};var y=class extends c{sortDirection=I;ascendingSort(){return this.sortDirection=I,this.sortByOrder()}descendingSort(){return this.sortDirection=k,this.sortByOrder()}sortByOrder(){return this.killed?!1:(this.subs.sort(this.sortDirection),!0)}subscribe(e,r){if(!this.isListener(e))return;let i=new d(this,!1);return this.addObserver(i,e,r),i}pipe(){if(this.killed)return;let e=new d(this,!0);return this.subs.push(e),e}unSubscribe(e){if(!this.killed){if(this.process&&e){this.trash.push(e);return}this.subs&&u(this.subs,e)}}};var m=class{arr=[];killed=!1;collect(...e){this.killed||this.arr.push(...e)}unsubscribe(e){this.killed||(e?.unsubscribe(),u(this.arr,e))}unsubscribeAll(){if(this.killed)return;let e=this.arr;for(let r=0;r<e.length;r++)e[r].unsubscribe();e.length=0}size(){return this.killed?0:this.arr.length}destroy(){this.unsubscribeAll(),this.arr.length=0,this.arr=0,this.killed=!0}get isDestroyed(){return this.killed}};export{m as Collector,c as Observable,y as OrderedObservable,u as deleteFromArray,C as quickDeleteFromArray};
|