@shuvi/utils 1.0.0-rc.2 → 1.0.0-rc.20

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/lib/async.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ export declare type Results<T = any> = T[] & {
2
+ first: T;
3
+ _firstFlag: boolean;
4
+ };
5
+ export declare type SimpleCallback = () => any;
6
+ export interface AsyncParallelIteratorCallback<T = unknown, E = unknown> {
7
+ (err?: E | null, value?: T): void;
8
+ }
9
+ export interface AsyncParallelIterator<T, E> {
10
+ (item: T, callback: AsyncParallelIteratorCallback<T, E>): void;
11
+ }
12
+ export interface AsyncIterator<T, E> {
13
+ (item: T, callback: ErrorCallback<E>): void;
14
+ }
15
+ export interface ErrorCallback<T> {
16
+ (err?: T | null): void;
17
+ }
18
+ export declare type AsyncParallelCallback<T, E> = (finishedNum: number, values: Results<T>, errors: Results<E>, done: SimpleCallback) => any;
19
+ export declare function each<T = unknown, E = unknown>(targets: T[], handler: AsyncIterator<T, E>, cb?: ErrorCallback<E>): void;
package/lib/async.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.each = void 0;
4
+ function runParallel(targets, handler, cb) {
5
+ const values = [];
6
+ const errors = [];
7
+ let finishedNum = 0;
8
+ let abort = false;
9
+ const done = () => {
10
+ abort = true;
11
+ };
12
+ if (targets.length <= 0) {
13
+ return cb(finishedNum, values, errors, done);
14
+ }
15
+ const handlerCallback = (index) => {
16
+ let called = false;
17
+ return (err, value) => {
18
+ if (called) {
19
+ return;
20
+ }
21
+ called = true;
22
+ if (abort) {
23
+ return;
24
+ }
25
+ finishedNum++;
26
+ if (err) {
27
+ if (!errors.first) {
28
+ errors.first = err;
29
+ }
30
+ errors[index] = err;
31
+ return cb(finishedNum, values, errors, done);
32
+ }
33
+ if (!values._firstFlag) {
34
+ values._firstFlag = true;
35
+ values[index] = value;
36
+ }
37
+ cb(finishedNum, values, errors, done);
38
+ };
39
+ };
40
+ targets.forEach((t, index) => {
41
+ handler(t, handlerCallback(index));
42
+ });
43
+ }
44
+ function each(targets, handler, cb) {
45
+ runParallel(targets, handler, (finishedNum, values, errors, done) => {
46
+ if (errors.first) {
47
+ done();
48
+ return cb && cb(errors.first);
49
+ }
50
+ if (finishedNum === targets.length) {
51
+ done();
52
+ cb && cb(null);
53
+ }
54
+ });
55
+ }
56
+ exports.each = each;
package/lib/defer.d.ts CHANGED
@@ -2,5 +2,6 @@ export interface Defer<T = void> {
2
2
  resolve(T?: T | PromiseLike<T>): void;
3
3
  reject(err: any): void;
4
4
  promise: Promise<T>;
5
+ status: 'pending' | 'fulfilled' | 'rejected';
5
6
  }
6
7
  export declare function createDefer<T>(): Defer<T>;
package/lib/defer.js CHANGED
@@ -4,11 +4,18 @@ exports.createDefer = void 0;
4
4
  function createDefer() {
5
5
  let defer = {
6
6
  resolve: null,
7
- reject: null
7
+ reject: null,
8
+ status: 'pending'
8
9
  };
9
10
  defer.promise = new Promise((resolve, reject) => {
10
- defer.resolve = resolve;
11
- defer.reject = reject;
11
+ defer.resolve = (value) => {
12
+ resolve(value);
13
+ defer.status = 'fulfilled';
14
+ };
15
+ defer.reject = (value) => {
16
+ reject(value);
17
+ defer.status = 'rejected';
18
+ };
12
19
  });
13
20
  return defer;
14
21
  }
@@ -0,0 +1,18 @@
1
+ declare type AnyHandler = (...args: any) => void;
2
+ export declare type RemoveListenerCallback = () => void | undefined;
3
+ export declare type Event<F extends AnyHandler> = {
4
+ toArray: () => F[];
5
+ length: number;
6
+ on: (fn: F) => RemoveListenerCallback;
7
+ emit: (...arg: Parameters<F>) => void;
8
+ };
9
+ export interface EventMap {
10
+ [key: string]: AnyHandler;
11
+ }
12
+ export declare type Events<EM extends EventMap = EventMap> = {
13
+ on<Name extends keyof EM, Handler = EM[Name]>(type: Name, handler: Handler): RemoveListenerCallback;
14
+ emit<Name extends keyof EM, Handler extends AnyHandler = EM[Name]>(type: string, ...args: Parameters<Handler>): void;
15
+ };
16
+ export declare function createEvent<F extends AnyHandler>(): Event<F>;
17
+ export declare function createEvents<EM extends EventMap = EventMap>(): Events<EM>;
18
+ export {};
package/lib/events.js ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createEvents = exports.createEvent = void 0;
4
+ function createEvent() {
5
+ let handlers = [];
6
+ return {
7
+ get length() {
8
+ return handlers.length;
9
+ },
10
+ toArray() {
11
+ return handlers;
12
+ },
13
+ on(fn) {
14
+ handlers.push(fn);
15
+ return function () {
16
+ handlers = handlers.filter(handler => handler !== fn);
17
+ };
18
+ },
19
+ emit(...arg) {
20
+ // @ts-ignore
21
+ handlers.forEach(fn => fn && fn(...arg));
22
+ }
23
+ };
24
+ }
25
+ exports.createEvent = createEvent;
26
+ function createEvents() {
27
+ const all = Object.create(null);
28
+ return {
29
+ on(type, handler) {
30
+ (all[type] || (all[type] = [])).push(handler);
31
+ return () => {
32
+ const index = all[type].indexOf(handler);
33
+ if (index > -1) {
34
+ all[type].splice(index, 1);
35
+ }
36
+ };
37
+ },
38
+ emit(type, ...args) {
39
+ (all[type] || []).slice().forEach(handler => {
40
+ // @ts-ignore
41
+ handler(...args);
42
+ });
43
+ }
44
+ };
45
+ }
46
+ exports.createEvents = createEvents;
@@ -1,5 +1,5 @@
1
- import { TimeInfo } from 'watchpack';
2
- export { TimeInfo };
1
+ import Watchpack, { TimeInfo } from 'watchpack';
2
+ export { Watchpack, TimeInfo };
3
3
  export interface WatchEvent {
4
4
  changes: string[];
5
5
  removals: string[];
@@ -9,7 +9,10 @@ export interface WatchOptions {
9
9
  files?: string[];
10
10
  directories?: string[];
11
11
  missing?: string[];
12
+ aggregateTimeout?: number;
12
13
  startTime?: number;
14
+ ignoreFileContentUpdate?: boolean;
13
15
  }
14
16
  export declare type WatchCallback = (event: WatchEvent) => void;
15
- export declare function watch({ files, directories, missing, startTime }: WatchOptions, cb: WatchCallback): () => void;
17
+ export declare type ChangeCallback = (file: string, time: number) => void;
18
+ export declare function watch({ files, directories, missing, aggregateTimeout, startTime, ignoreFileContentUpdate }: WatchOptions, callback: WatchCallback, callbackUndelayed?: ChangeCallback): () => void;
@@ -3,8 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.watch = void 0;
6
+ exports.watch = exports.Watchpack = void 0;
7
7
  const watchpack_1 = __importDefault(require("watchpack"));
8
+ exports.Watchpack = watchpack_1.default;
9
+ const watchpackExplanationType = {
10
+ change: 'change',
11
+ rename: 'rename'
12
+ };
8
13
  const options = {
9
14
  // options:
10
15
  aggregateTimeout: 300,
@@ -16,17 +21,30 @@ const options = {
16
21
  // ignored: /regexp/ - a regular expression for files or folders that should not be watched
17
22
  // All subdirectories are ignored too
18
23
  };
19
- function watch({ files, directories, missing, startTime = Date.now() }, cb) {
20
- const wp = new watchpack_1.default(options);
21
- wp.on('aggregated', (changes, removals) => {
24
+ function watch({ files, directories, missing, aggregateTimeout, startTime = Date.now(), ignoreFileContentUpdate }, callback, callbackUndelayed) {
25
+ const watchPackOptions = Object.assign({}, options);
26
+ if (aggregateTimeout !== undefined) {
27
+ watchPackOptions.aggregateTimeout = aggregateTimeout;
28
+ }
29
+ const wp = new watchpack_1.default(watchPackOptions);
30
+ let aggregatedChanges = new Set();
31
+ let aggregatedRemovals = new Set();
32
+ wp.on('aggregated', () => {
33
+ if (!aggregatedChanges.size && !aggregatedRemovals.size) {
34
+ return;
35
+ }
22
36
  const knownFiles = wp.getTimeInfoEntries();
23
- cb({
24
- changes: Array.from(changes),
25
- removals: Array.from(removals),
37
+ const changes = Array.from(aggregatedChanges);
38
+ const removals = Array.from(aggregatedRemovals);
39
+ aggregatedChanges = new Set();
40
+ aggregatedRemovals = new Set();
41
+ callback({
42
+ changes,
43
+ removals,
26
44
  getAllFiles() {
27
45
  const res = [];
28
- for (const [file, timeinfo] of knownFiles.entries()) {
29
- if (timeinfo && timeinfo.accuracy !== undefined) {
46
+ for (const [file, timeInfo] of knownFiles.entries()) {
47
+ if (timeInfo && timeInfo.accuracy !== undefined) {
30
48
  res.push(file);
31
49
  }
32
50
  }
@@ -34,8 +52,28 @@ function watch({ files, directories, missing, startTime = Date.now() }, cb) {
34
52
  }
35
53
  });
36
54
  });
55
+ wp.on('change', (file, time, explanation) => {
56
+ if (ignoreFileContentUpdate &&
57
+ explanation === watchpackExplanationType.change) {
58
+ return;
59
+ }
60
+ aggregatedRemovals.delete(file);
61
+ aggregatedChanges.add(file);
62
+ callbackUndelayed === null || callbackUndelayed === void 0 ? void 0 : callbackUndelayed(file, time);
63
+ });
64
+ wp.on('remove', (file, time, explanation) => {
65
+ if (ignoreFileContentUpdate &&
66
+ explanation === watchpackExplanationType.change) {
67
+ return;
68
+ }
69
+ aggregatedChanges.delete(file);
70
+ aggregatedRemovals.add(file);
71
+ callbackUndelayed === null || callbackUndelayed === void 0 ? void 0 : callbackUndelayed(file, time);
72
+ });
37
73
  wp.watch({ files, directories, missing, startTime });
38
74
  return () => {
75
+ aggregatedChanges.clear();
76
+ aggregatedRemovals.clear();
39
77
  wp.close();
40
78
  };
41
79
  }
package/lib/logger.d.ts CHANGED
@@ -4,4 +4,17 @@ export interface Logger {
4
4
  warn(...args: any[]): void;
5
5
  error(...args: any[]): void;
6
6
  }
7
- export default function logger(namespace: string): Logger;
7
+ export declare const colorize: {
8
+ error: (...message: any[]) => string;
9
+ warn: (...message: any[]) => string;
10
+ };
11
+ declare class LoggerImpl implements Logger {
12
+ private _debug;
13
+ constructor(namespace: string);
14
+ debug(formatter: any, ...args: any[]): void;
15
+ info(...args: any[]): void;
16
+ warn(...args: any[]): void;
17
+ error(...args: any[]): void;
18
+ }
19
+ declare const _default: LoggerImpl;
20
+ export default _default;
package/lib/logger.js CHANGED
@@ -3,7 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.colorize = void 0;
6
7
  const debug_1 = __importDefault(require("debug"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ exports.colorize = {
10
+ error: (...message) => chalk_1.default.red(...message),
11
+ warn: (...message) => chalk_1.default.yellow(...message)
12
+ };
7
13
  class LoggerImpl {
8
14
  constructor(namespace) {
9
15
  this._debug = (0, debug_1.default)(namespace);
@@ -12,16 +18,13 @@ class LoggerImpl {
12
18
  this._debug(formatter, ...args);
13
19
  }
14
20
  info(...args) {
15
- console.log("INFO:", ...args);
21
+ console.log(...args);
16
22
  }
17
23
  warn(...args) {
18
- console.warn("WARN:", ...args);
24
+ console.warn(exports.colorize.warn(...args));
19
25
  }
20
26
  error(...args) {
21
- console.error("ERROR:", ...args);
27
+ console.error(exports.colorize.error(...args));
22
28
  }
23
29
  }
24
- function logger(namespace) {
25
- return new LoggerImpl(namespace);
26
- }
27
- exports.default = logger;
30
+ exports.default = new LoggerImpl('shuvi');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuvi/utils",
3
- "version": "1.0.0-rc.2",
3
+ "version": "1.0.0-rc.20",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/shuvijs/shuvi.git",
@@ -28,7 +28,7 @@
28
28
  "resolve": "1.22.1",
29
29
  "schema-utils": "^3.0.0",
30
30
  "tiny-invariant": "1.1.0",
31
- "watchpack": "2.1.0"
31
+ "watchpack": "^2.4.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/debug": "^4.1.5",
@@ -1,8 +0,0 @@
1
- declare type Handler = (...evts: any[]) => void;
2
- export declare type EventEmitter<F extends Function = Handler> = {
3
- on(type: string, handler: F): void;
4
- off(type: string, handler: F): void;
5
- emit(type: string, ...evts: any[]): void;
6
- };
7
- export default function emitter<F extends Function = Handler>(): EventEmitter<F>;
8
- export {};
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- function emitter() {
4
- const all = Object.create(null);
5
- return {
6
- on(type, handler) {
7
- (all[type] || (all[type] = [])).push(handler);
8
- },
9
- off(type, handler) {
10
- if (all[type]) {
11
- const index = all[type].indexOf(handler);
12
- if (index >= 0) {
13
- all[type].splice(index, 1);
14
- }
15
- }
16
- },
17
- emit(type, ...evts) {
18
- (all[type] || []).slice().forEach((handler) => {
19
- handler(...evts);
20
- });
21
- }
22
- };
23
- }
24
- exports.default = emitter;