-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- port from TS to JS - ESM only support - use node built-in test runner - use JsDoc for types
- Loading branch information
Showing
98 changed files
with
4,613 additions
and
16,396 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,37 @@ | ||
{ | ||
"parser": "@typescript-eslint/parser", | ||
"parserOptions": { | ||
"ecmaVersion": 2018, | ||
"sourceType": "module" | ||
}, | ||
"extends": [ | ||
"plugin:@typescript-eslint/recommended", | ||
"plugin:prettier/recommended" | ||
], | ||
"rules": { | ||
"prefer-arrow-callback": "error", | ||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }], | ||
"no-param-reassign": "error", | ||
"no-shadow": "error", | ||
"no-console": "error", | ||
"max-classes-per-file": "error", | ||
"complexity": "error", | ||
"no-empty": "error", | ||
"curly": "error", | ||
"max-len": ["error", {"code": 132, "comments": 162}], | ||
"max-lines": ["error", 1000], | ||
"quotes": ["error", "single"], | ||
"newline-per-chained-call": ["error", { "ignoreChainWithDepth": 2 }], | ||
"@typescript-eslint/no-explicit-any": "error", | ||
"@typescript-eslint/no-magic-numbers": ["error", { "ignore": [-1, 0, 1, 2] }], | ||
"@typescript-eslint/no-empty-interface": "error", | ||
"@typescript-eslint/prefer-for-of": "error", | ||
"@typescript-eslint/explicit-module-boundary-types": "error", | ||
"prettier/prettier": ["warn"] | ||
"root": true, | ||
"parserOptions": { | ||
"ecmaVersion": 2022, // Top-level await, etc. | ||
"sourceType": "module", | ||
"ecmaFeatures": { | ||
} | ||
} | ||
}, | ||
"env": { | ||
"node": true, | ||
"es2022": true // Defines `Promise`, etc. | ||
}, | ||
"extends": [ | ||
"eslint:recommended", | ||
"plugin:prettier/recommended" | ||
], | ||
"rules": { | ||
"prefer-arrow-callback": "error", | ||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }], | ||
"no-param-reassign": "error", | ||
"no-shadow": "error", | ||
"no-console": "error", | ||
"max-classes-per-file": "error", | ||
"complexity": "error", | ||
"no-empty": "error", | ||
"curly": "error", | ||
"max-len": ["error", {"code": 132, "comments": 162}], | ||
"max-lines": ["error", 1000], | ||
"quotes": ["error", "single"], | ||
"newline-per-chained-call": ["error", { "ignoreChainWithDepth": 2 }], | ||
"prettier/prettier": ["warn"] | ||
}, | ||
"ignorePatterns": [ | ||
"node_modules", | ||
".tap" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,4 @@ | |
node_modules | ||
|
||
# test artifacts | ||
/coverage | ||
|
||
# build artifacts | ||
/lib | ||
test-report-* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
20.9.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
{ | ||
"parser": "typescript", | ||
"printWidth": 120, | ||
"tabWidth": 2, | ||
"singleQuote": true, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"typescript.tsdk": "node_modules/typescript/lib" | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { createObsevable } from '../observable.js'; | ||
|
||
/** | ||
* @typedef {Object} ValueSlot | ||
* @property {import('../types').Subscription} subscription | ||
* @property {unknown} [value] | ||
*/ | ||
|
||
/** | ||
* Returns true if te object has a property named "value" | ||
* @param {Object} o | ||
* @returns {boolean} | ||
*/ | ||
function withValue(o) { | ||
return Object.prototype.hasOwnProperty.call(o, 'value'); | ||
} | ||
|
||
/** | ||
* @param {...import('../types').Observable<any>} observables | ||
* @returns {import('../types').Observable<any>} | ||
*/ | ||
export function combineLatest(...observables) { | ||
return createObsevable((observer) => { | ||
/** @type {ValueSlot[]} */ | ||
const slots = []; | ||
let completedSubscriptions = 0; | ||
|
||
/** @type {(i: number) => import('../types').Observer<any>} */ | ||
const indexedObserver = (index) => ({ | ||
next: (value) => { | ||
slots[index].value = value; | ||
if (slots.every(withValue)) { | ||
observer.next(slots.map((s) => s.value)); | ||
} | ||
}, | ||
error: (err) => { | ||
observer.error(err); | ||
}, | ||
complete: () => { | ||
completedSubscriptions++; | ||
if (completedSubscriptions === slots.length) { | ||
observer.complete(); | ||
} | ||
}, | ||
}); | ||
|
||
observables.forEach((observable, index) => { | ||
slots.push({ subscription: observable.subscribe(indexedObserver(index)) }); | ||
}); | ||
|
||
return () => { | ||
slots.forEach((slot) => { | ||
slot.subscription.unsubscribe(); | ||
}); | ||
}; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { createObsevable } from '../observable.js'; | ||
|
||
/** | ||
* @param {...import('../types').Observable<any>} observables | ||
* @returns {import('../types').Observable<any>} | ||
*/ | ||
export function concat(...observables) { | ||
return createObsevable((observer) => { | ||
/** @type {import('../types').Observer<any>} */ | ||
const innerObserver = { | ||
next: (value) => { | ||
observer.next(value); | ||
}, | ||
error: (err) => { | ||
observer.error(err); | ||
}, | ||
complete: () => { | ||
activeSubscription.unsubscribe(); | ||
observables.shift(); | ||
if (observables.length === 0) { | ||
observer.complete(); | ||
activeSubscription = null; | ||
} else { | ||
activeSubscription = observables[0].subscribe(innerObserver); | ||
} | ||
}, | ||
}; | ||
|
||
let activeSubscription = observables[0].subscribe(innerObserver); | ||
|
||
return () => { | ||
if (activeSubscription) { | ||
activeSubscription.unsubscribe(); | ||
} | ||
}; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { Observable } from '../observable.js'; | ||
|
||
function isPromiseLike(target) { | ||
return typeof target?.then === 'function'; | ||
} | ||
function isArrayLike(target) { | ||
return typeof target?.length === 'number'; | ||
} | ||
function isObservable(target) { | ||
return typeof target?.subscribe === 'function'; | ||
} | ||
|
||
/** | ||
* @template T | ||
* @param {PromiseLike<T>} promise | ||
* @returns {import('../types').Observable<T>} | ||
*/ | ||
function fromPromise(promise) { | ||
return new Observable((observer) => { | ||
promise.then( | ||
(value) => { | ||
observer.next(value); | ||
observer.complete(); | ||
}, | ||
(error) => { | ||
observer.error(error); | ||
}, | ||
); | ||
}); | ||
} | ||
|
||
/** | ||
* @template T | ||
* @param {ArrayLike<T>} array | ||
* @returns {import('../types').Observable<T>} | ||
*/ | ||
function fromArray(array) { | ||
return new Observable((observer) => { | ||
for (let i = 0; i < array.length; i++) { | ||
observer.next(array[i]); | ||
} | ||
observer.complete(); | ||
}); | ||
} | ||
|
||
/** | ||
* @template T | ||
* @param {import('../types').ObservableInput<T>} input | ||
* @returns {import('../types').Observable<T>} | ||
*/ | ||
export function from(input) { | ||
if (isPromiseLike(input)) { | ||
// @ts-ignore | ||
return fromPromise(input); | ||
} | ||
if (isArrayLike(input)) { | ||
// @ts-ignore | ||
return fromArray(input); | ||
} | ||
if (isObservable(input)) { | ||
// @ts-ignore | ||
return input; | ||
} | ||
throw new Error('cannot create an observable for the given input'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { createObsevable } from '../observable.js'; | ||
|
||
/** | ||
* @param {import('../types').EventTargetLike<any>} target | ||
* @param {string} eventName | ||
* @returns {import('../types').Observable<any>} | ||
*/ | ||
function fromEventTarget(target, eventName) { | ||
return createObsevable((observer) => { | ||
const handler = (event) => observer.next(event); | ||
|
||
target.addEventListener(eventName, handler); | ||
return () => { | ||
target.removeEventListener(eventName, handler); | ||
}; | ||
}); | ||
} | ||
|
||
/** | ||
* @param {import('../types').EventEmitterLike<any>} target | ||
* @param {string} eventName | ||
* @returns {import('../types').Observable<any>} | ||
*/ | ||
function fromEventEmitter(target, eventName) { | ||
return createObsevable((observer) => { | ||
const handler = (...args) => observer.next(args); | ||
|
||
target.addListener(eventName, handler); | ||
return () => { | ||
target.removeListener(eventName, handler); | ||
}; | ||
}); | ||
} | ||
|
||
// /** | ||
// * Returns an observable from | ||
// * @param {any} target | ||
// * @param {string} eventName | ||
// * @returns {import('../types').Observable<any>} | ||
// */ | ||
export function fromEvent(target, eventName) { | ||
if (typeof target.addEventListener === 'function') { | ||
return fromEventTarget(target, eventName); | ||
} else if (typeof target.addListener === 'function') { | ||
return fromEventEmitter(target, eventName); | ||
} | ||
|
||
throw new Error('cannot create an observable for the given input'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { createObsevable } from '../observable.js'; | ||
|
||
/** | ||
* @typedef {(...args: unknown[]) => void} EventHandlerLike | ||
*/ | ||
|
||
/** | ||
* @template T | ||
* @param {(handler: EventHandlerLike) => unknown} addHandler | ||
* @param {(handler: EventHandlerLike, signal: unknown) => unknown} removeHandler | ||
* @param {(...args: any[]) => T} [project] | ||
* @returns {import('../types').Observable<T>} | ||
*/ | ||
export function fromEventPattern(addHandler, removeHandler, project) { | ||
return createObsevable((observer) => { | ||
const handler = (...args) => observer.next(project ? project(...args) : args[0]); | ||
const signal = addHandler(handler); | ||
return () => { | ||
removeHandler(handler, signal); | ||
}; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export * from './combineLatest.js'; | ||
export * from './concat.js'; | ||
export * from './from.js'; | ||
export * from './fromEvent.js'; | ||
export * from './fromEventPattern.js'; | ||
export * from './interval.js'; | ||
export * from './merge.js'; | ||
export * from './of.js'; | ||
export * from './sequence.js'; | ||
export * from './timer.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { createObsevable } from '../observable.js'; | ||
|
||
/** | ||
* @param {number} period | ||
* @returns {import('../types').Observable<number>} | ||
*/ | ||
export function interval(period) { | ||
return createObsevable((observer) => { | ||
let index = 0; | ||
const id = setInterval(() => observer.next(index++), period); | ||
return () => { | ||
clearInterval(id); | ||
}; | ||
}); | ||
} |
Oops, something went wrong.