zeed 1.3.0 → 1.4.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/AGENTS.md +50 -211
- package/README.md +16 -0
- package/dist/_experiments/bitcask.cjs +243 -1
- package/dist/_experiments/bitcask.cjs.map +1 -1
- package/dist/_experiments/bitcask.mjs +230 -1
- package/dist/_experiments/bitcask.mjs.map +1 -1
- package/dist/bin-BAoS4qtm.mjs +593 -0
- package/dist/{bin-SPdenYkw.mjs.map → bin-BAoS4qtm.mjs.map} +1 -1
- package/dist/bin-Ddaz2lxM.cjs +862 -0
- package/dist/{bin-Ce3i6ABn.cjs.map → bin-Ddaz2lxM.cjs.map} +1 -1
- package/dist/browser/base64.cjs +14 -1
- package/dist/browser/base64.cjs.map +1 -1
- package/dist/browser/base64.mjs +12 -1
- package/dist/browser/base64.mjs.map +1 -1
- package/dist/browser/gravatar.cjs +186 -1
- package/dist/browser/gravatar.cjs.map +1 -1
- package/dist/browser/gravatar.mjs +184 -1
- package/dist/browser/gravatar.mjs.map +1 -1
- package/dist/browser/index.cjs +14 -1
- package/dist/browser/index.mjs +8 -1
- package/dist/browser/localstorage.cjs +46 -1
- package/dist/browser/localstorage.cjs.map +1 -1
- package/dist/browser/localstorage.mjs +45 -1
- package/dist/browser/localstorage.mjs.map +1 -1
- package/dist/browser/log/index.cjs +8 -1
- package/dist/browser/log/index.mjs +5 -1
- package/dist/browser/log/log-browser-factory.cjs +65 -1
- package/dist/browser/log/log-browser-factory.cjs.map +1 -1
- package/dist/browser/log/log-browser-factory.mjs +64 -1
- package/dist/browser/log/log-browser-factory.mjs.map +1 -1
- package/dist/browser/log/log-browser.cjs +72 -1
- package/dist/browser/log/log-browser.cjs.map +1 -1
- package/dist/browser/log/log-browser.mjs +71 -1
- package/dist/browser/log/log-browser.mjs.map +1 -1
- package/dist/browser/log/log-colors.cjs +11 -1
- package/dist/browser/log/log-colors.cjs.map +1 -1
- package/dist/browser/log/log-colors.mjs +9 -1
- package/dist/browser/log/log-colors.mjs.map +1 -1
- package/dist/browser/log/log-context-browser.cjs +25 -1
- package/dist/browser/log/log-context-browser.cjs.map +1 -1
- package/dist/browser/log/log-context-browser.mjs +23 -1
- package/dist/browser/log/log-context-browser.mjs.map +1 -1
- package/dist/chunk-DQk6qfdC.mjs +18 -0
- package/dist/chunk-uaV2rQ02.cjs +53 -0
- package/dist/common/assert.cjs +22 -1
- package/dist/common/assert.cjs.map +1 -1
- package/dist/common/assert.mjs +19 -1
- package/dist/common/assert.mjs.map +1 -1
- package/dist/common/bin/index.cjs +106 -1
- package/dist/common/bin/index.cjs.map +1 -1
- package/dist/common/bin/index.mjs +98 -1
- package/dist/common/bin/index.mjs.map +1 -1
- package/dist/common/bin/lib0/binary.cjs +146 -1
- package/dist/common/bin/lib0/binary.cjs.map +1 -1
- package/dist/common/bin/lib0/binary.mjs +80 -1
- package/dist/common/bin/lib0/binary.mjs.map +1 -1
- package/dist/common/bin/lib0/buffer.cjs +42 -1
- package/dist/common/bin/lib0/buffer.cjs.map +1 -1
- package/dist/common/bin/lib0/buffer.mjs +38 -1
- package/dist/common/bin/lib0/buffer.mjs.map +1 -1
- package/dist/common/bin/lib0/create.cjs +24 -1
- package/dist/common/bin/lib0/create.cjs.map +1 -1
- package/dist/common/bin/lib0/create.mjs +21 -1
- package/dist/common/bin/lib0/create.mjs.map +1 -1
- package/dist/common/bin/lib0/decoding.cjs +325 -1
- package/dist/common/bin/lib0/decoding.cjs.map +1 -1
- package/dist/common/bin/lib0/decoding.mjs +298 -1
- package/dist/common/bin/lib0/decoding.mjs.map +1 -1
- package/dist/common/bin/lib0/encoding.cjs +404 -1
- package/dist/common/bin/lib0/encoding.cjs.map +1 -1
- package/dist/common/bin/lib0/encoding.mjs +377 -1
- package/dist/common/bin/lib0/encoding.mjs.map +1 -1
- package/dist/common/bin/lib0/string.cjs +81 -1
- package/dist/common/bin/lib0/string.cjs.map +1 -1
- package/dist/common/bin/lib0/string.mjs +71 -1
- package/dist/common/bin/lib0/string.mjs.map +1 -1
- package/dist/common/crypto/aes-sealed.cjs +34 -1
- package/dist/common/crypto/aes-sealed.cjs.map +1 -1
- package/dist/common/crypto/aes-sealed.mjs +32 -1
- package/dist/common/crypto/aes-sealed.mjs.map +1 -1
- package/dist/common/crypto/crypto.cjs +91 -1
- package/dist/common/crypto/crypto.cjs.map +1 -1
- package/dist/common/crypto/crypto.mjs +80 -1
- package/dist/common/crypto/crypto.mjs.map +1 -1
- package/dist/common/crypto/index.cjs +23 -1
- package/dist/common/crypto/index.mjs +5 -1
- package/dist/common/crypto/xaes.cjs +128 -1
- package/dist/common/crypto/xaes.cjs.map +1 -1
- package/dist/common/crypto/xaes.mjs +123 -1
- package/dist/common/crypto/xaes.mjs.map +1 -1
- package/dist/common/csv.cjs +49 -4
- package/dist/common/csv.cjs.map +1 -1
- package/dist/common/csv.mjs +46 -4
- package/dist/common/csv.mjs.map +1 -1
- package/dist/common/data/array.cjs +299 -1
- package/dist/common/data/array.cjs.map +1 -1
- package/dist/common/data/array.mjs +274 -1
- package/dist/common/data/array.mjs.map +1 -1
- package/dist/common/data/basex-secure.cjs +30 -1
- package/dist/common/data/basex-secure.mjs +3 -1
- package/dist/common/data/basex.cjs +163 -1
- package/dist/common/data/basex.cjs.map +1 -1
- package/dist/common/data/basex.mjs +152 -1
- package/dist/common/data/basex.mjs.map +1 -1
- package/dist/common/data/bin-types.mjs +1 -1
- package/dist/common/data/bin.cjs +21 -1
- package/dist/common/data/bin.mjs +3 -1
- package/dist/common/data/camelcase.cjs +27 -1
- package/dist/common/data/camelcase.cjs.map +1 -1
- package/dist/common/data/camelcase.mjs +22 -1
- package/dist/common/data/camelcase.mjs.map +1 -1
- package/dist/common/data/convert.cjs +104 -1
- package/dist/common/data/convert.cjs.map +1 -1
- package/dist/common/data/convert.mjs +88 -1
- package/dist/common/data/convert.mjs.map +1 -1
- package/dist/common/data/datauri.cjs +32 -1
- package/dist/common/data/datauri.cjs.map +1 -1
- package/dist/common/data/datauri.mjs +27 -1
- package/dist/common/data/datauri.mjs.map +1 -1
- package/dist/common/data/day-legacy.cjs +148 -1
- package/dist/common/data/day-legacy.cjs.map +1 -1
- package/dist/common/data/day-legacy.mjs +143 -1
- package/dist/common/data/day-legacy.mjs.map +1 -1
- package/dist/common/data/day.cjs +335 -1
- package/dist/common/data/day.cjs.map +1 -1
- package/dist/common/data/day.mjs +305 -1
- package/dist/common/data/day.mjs.map +1 -1
- package/dist/common/data/decimal.cjs +28 -1
- package/dist/common/data/decimal.cjs.map +1 -1
- package/dist/common/data/decimal.mjs +23 -1
- package/dist/common/data/decimal.mjs.map +1 -1
- package/dist/common/data/deep.cjs +57 -1
- package/dist/common/data/deep.cjs.map +1 -1
- package/dist/common/data/deep.mjs +54 -1
- package/dist/common/data/deep.mjs.map +1 -1
- package/dist/common/data/diff.cjs +62 -1
- package/dist/common/data/diff.cjs.map +1 -1
- package/dist/common/data/diff.mjs +60 -1
- package/dist/common/data/diff.mjs.map +1 -1
- package/dist/common/data/distributed.cjs +24 -1
- package/dist/common/data/distributed.cjs.map +1 -1
- package/dist/common/data/distributed.mjs +22 -1
- package/dist/common/data/distributed.mjs.map +1 -1
- package/dist/common/data/format.cjs +63 -1
- package/dist/common/data/format.cjs.map +1 -1
- package/dist/common/data/format.mjs +59 -1
- package/dist/common/data/format.mjs.map +1 -1
- package/dist/common/data/html.cjs +13 -1
- package/dist/common/data/html.cjs.map +1 -1
- package/dist/common/data/html.mjs +10 -1
- package/dist/common/data/html.mjs.map +1 -1
- package/dist/common/data/index.cjs +296 -1
- package/dist/common/data/index.mjs +37 -1
- package/dist/common/data/is.cjs +106 -1
- package/dist/common/data/is.cjs.map +1 -1
- package/dist/common/data/is.mjs +85 -1
- package/dist/common/data/is.mjs.map +1 -1
- package/dist/common/data/json.cjs +70 -1
- package/dist/common/data/json.cjs.map +1 -1
- package/dist/common/data/json.mjs +65 -1
- package/dist/common/data/json.mjs.map +1 -1
- package/dist/common/data/list.cjs +32 -1
- package/dist/common/data/list.cjs.map +1 -1
- package/dist/common/data/list.mjs +27 -1
- package/dist/common/data/list.mjs.map +1 -1
- package/dist/common/data/lru.mjs +1 -1
- package/dist/common/data/math.cjs +79 -1
- package/dist/common/data/math.cjs.map +1 -1
- package/dist/common/data/math.mjs +65 -1
- package/dist/common/data/math.mjs.map +1 -1
- package/dist/common/data/message.cjs +30 -1
- package/dist/common/data/message.cjs.map +1 -1
- package/dist/common/data/message.mjs +28 -1
- package/dist/common/data/message.mjs.map +1 -1
- package/dist/common/data/object-changes.cjs +66 -1
- package/dist/common/data/object-changes.cjs.map +1 -1
- package/dist/common/data/object-changes.mjs +63 -1
- package/dist/common/data/object-changes.mjs.map +1 -1
- package/dist/common/data/object.cjs +112 -1
- package/dist/common/data/object.cjs.map +1 -1
- package/dist/common/data/object.mjs +104 -1
- package/dist/common/data/object.mjs.map +1 -1
- package/dist/common/data/orderby.cjs +42 -1
- package/dist/common/data/orderby.cjs.map +1 -1
- package/dist/common/data/orderby.mjs +37 -1
- package/dist/common/data/orderby.mjs.map +1 -1
- package/dist/common/data/path.cjs +26 -1
- package/dist/common/data/path.cjs.map +1 -1
- package/dist/common/data/path.mjs +25 -1
- package/dist/common/data/path.mjs.map +1 -1
- package/dist/common/data/regexp.cjs +12 -1
- package/dist/common/data/regexp.cjs.map +1 -1
- package/dist/common/data/regexp.mjs +10 -1
- package/dist/common/data/regexp.mjs.map +1 -1
- package/dist/common/data/rounding.cjs +107 -1
- package/dist/common/data/rounding.cjs.map +1 -1
- package/dist/common/data/rounding.mjs +95 -1
- package/dist/common/data/rounding.mjs.map +1 -1
- package/dist/common/data/signal.cjs +39 -1
- package/dist/common/data/signal.cjs.map +1 -1
- package/dist/common/data/signal.mjs +38 -1
- package/dist/common/data/signal.mjs.map +1 -1
- package/dist/common/data/sortable.cjs +35 -1
- package/dist/common/data/sortable.cjs.map +1 -1
- package/dist/common/data/sortable.mjs +31 -1
- package/dist/common/data/sortable.mjs.map +1 -1
- package/dist/common/data/sorted.cjs +54 -1
- package/dist/common/data/sorted.cjs.map +1 -1
- package/dist/common/data/sorted.mjs +53 -1
- package/dist/common/data/sorted.mjs.map +1 -1
- package/dist/common/data/string-deburr.cjs +240 -1
- package/dist/common/data/string-deburr.cjs.map +1 -1
- package/dist/common/data/string-deburr.mjs +238 -1
- package/dist/common/data/string-deburr.mjs.map +1 -1
- package/dist/common/data/string-hash-fnv.cjs +69 -1
- package/dist/common/data/string-hash-fnv.cjs.map +1 -1
- package/dist/common/data/string-hash-fnv.mjs +67 -1
- package/dist/common/data/string-hash-fnv.mjs.map +1 -1
- package/dist/common/data/string-hash-pool.cjs +28 -1
- package/dist/common/data/string-hash-pool.cjs.map +1 -1
- package/dist/common/data/string-hash-pool.mjs +27 -1
- package/dist/common/data/string-hash-pool.mjs.map +1 -1
- package/dist/common/data/url.cjs +98 -2
- package/dist/common/data/url.cjs.map +1 -1
- package/dist/common/data/url.mjs +91 -2
- package/dist/common/data/url.mjs.map +1 -1
- package/dist/common/data/utils.cjs +118 -1
- package/dist/common/data/utils.cjs.map +1 -1
- package/dist/common/data/utils.mjs +107 -1
- package/dist/common/data/utils.mjs.map +1 -1
- package/dist/common/data/wordlist.cjs +531 -1
- package/dist/common/data/wordlist.cjs.map +1 -1
- package/dist/common/data/wordlist.mjs +529 -1
- package/dist/common/data/wordlist.mjs.map +1 -1
- package/dist/common/data/xrx.cjs +96 -1
- package/dist/common/data/xrx.cjs.map +1 -1
- package/dist/common/data/xrx.mjs +92 -1
- package/dist/common/data/xrx.mjs.map +1 -1
- package/dist/common/dispose-defer.cjs +133 -1
- package/dist/common/dispose-defer.cjs.map +1 -1
- package/dist/common/dispose-defer.mjs +130 -1
- package/dist/common/dispose-defer.mjs.map +1 -1
- package/dist/common/dispose-types.mjs +1 -1
- package/dist/common/dispose-utils.cjs +113 -1
- package/dist/common/dispose-utils.cjs.map +1 -1
- package/dist/common/dispose-utils.mjs +106 -1
- package/dist/common/dispose-utils.mjs.map +1 -1
- package/dist/common/exec/index.cjs +24 -1
- package/dist/common/exec/index.d.cts +1 -1
- package/dist/common/exec/index.d.mts +1 -1
- package/dist/common/exec/index.mjs +8 -1
- package/dist/common/exec/mutex.cjs +44 -1
- package/dist/common/exec/mutex.cjs.map +1 -1
- package/dist/common/exec/mutex.mjs +42 -1
- package/dist/common/exec/mutex.mjs.map +1 -1
- package/dist/common/exec/pool.cjs +181 -1
- package/dist/common/exec/pool.cjs.map +1 -1
- package/dist/common/exec/pool.d.cts +1 -1
- package/dist/common/exec/pool.d.mts +1 -1
- package/dist/common/exec/pool.mjs +180 -1
- package/dist/common/exec/pool.mjs.map +1 -1
- package/dist/common/exec/progress.cjs +149 -1
- package/dist/common/exec/progress.cjs.map +1 -1
- package/dist/common/exec/progress.d.cts +1 -1
- package/dist/common/exec/progress.d.mts +1 -1
- package/dist/common/exec/progress.mjs +148 -1
- package/dist/common/exec/progress.mjs.map +1 -1
- package/dist/common/exec/promise.cjs +113 -1
- package/dist/common/exec/promise.cjs.map +1 -1
- package/dist/common/exec/promise.mjs +103 -1
- package/dist/common/exec/promise.mjs.map +1 -1
- package/dist/common/exec/queue.cjs +125 -1
- package/dist/common/exec/queue.cjs.map +1 -1
- package/dist/common/exec/queue.d.cts +1 -1
- package/dist/common/exec/queue.d.mts +1 -1
- package/dist/common/exec/queue.mjs +124 -1
- package/dist/common/exec/queue.mjs.map +1 -1
- package/dist/common/exec/throttle-debounce.cjs +114 -1
- package/dist/common/exec/throttle-debounce.cjs.map +1 -1
- package/dist/common/exec/throttle-debounce.mjs +112 -1
- package/dist/common/exec/throttle-debounce.mjs.map +1 -1
- package/dist/common/global.cjs +22 -1
- package/dist/common/global.cjs.map +1 -1
- package/dist/common/global.mjs +19 -1
- package/dist/common/global.mjs.map +1 -1
- package/dist/common/index.cjs +559 -1
- package/dist/common/index.d.cts +1 -1
- package/dist/common/index.d.mts +1 -1
- package/dist/common/index.mjs +89 -1
- package/dist/common/localhost.cjs +16 -1
- package/dist/common/localhost.cjs.map +1 -1
- package/dist/common/localhost.mjs +14 -1
- package/dist/common/localhost.mjs.map +1 -1
- package/dist/common/log/index.cjs +34 -1
- package/dist/common/log/index.mjs +11 -1
- package/dist/common/log/log-base.cjs +40 -1
- package/dist/common/log/log-base.cjs.map +1 -1
- package/dist/common/log/log-base.mjs +31 -1
- package/dist/common/log/log-base.mjs.map +1 -1
- package/dist/common/log/log-colors.cjs +92 -1
- package/dist/common/log/log-colors.cjs.map +1 -1
- package/dist/common/log/log-colors.mjs +90 -1
- package/dist/common/log/log-colors.mjs.map +1 -1
- package/dist/common/log/log-config.cjs +15 -1
- package/dist/common/log/log-config.cjs.map +1 -1
- package/dist/common/log/log-config.mjs +14 -1
- package/dist/common/log/log-config.mjs.map +1 -1
- package/dist/common/log/log-console-capture.cjs +33 -1
- package/dist/common/log/log-console-capture.cjs.map +1 -1
- package/dist/common/log/log-console-capture.mjs +32 -1
- package/dist/common/log/log-console-capture.mjs.map +1 -1
- package/dist/common/log/log-console-original.cjs +27 -1
- package/dist/common/log/log-console-original.cjs.map +1 -1
- package/dist/common/log/log-console-original.mjs +26 -1
- package/dist/common/log/log-console-original.mjs.map +1 -1
- package/dist/common/log/log-console.cjs +39 -1
- package/dist/common/log/log-console.cjs.map +1 -1
- package/dist/common/log/log-console.mjs +38 -1
- package/dist/common/log/log-console.mjs.map +1 -1
- package/dist/common/log/log-context.cjs +109 -1
- package/dist/common/log/log-context.cjs.map +1 -1
- package/dist/common/log/log-context.mjs +108 -1
- package/dist/common/log/log-context.mjs.map +1 -1
- package/dist/common/log/log-filter.cjs +80 -1
- package/dist/common/log/log-filter.cjs.map +1 -1
- package/dist/common/log/log-filter.mjs +75 -1
- package/dist/common/log/log-filter.mjs.map +1 -1
- package/dist/common/log/log-memory.cjs +45 -1
- package/dist/common/log/log-memory.cjs.map +1 -1
- package/dist/common/log/log-memory.mjs +43 -1
- package/dist/common/log/log-memory.mjs.map +1 -1
- package/dist/common/log/log-noop.cjs +17 -1
- package/dist/common/log/log-noop.cjs.map +1 -1
- package/dist/common/log/log-noop.mjs +15 -1
- package/dist/common/log/log-noop.mjs.map +1 -1
- package/dist/common/log/log.cjs +46 -1
- package/dist/common/log/log.cjs.map +1 -1
- package/dist/common/log/log.mjs +43 -1
- package/dist/common/log/log.mjs.map +1 -1
- package/dist/common/msg/channel-debug.cjs +17 -1
- package/dist/common/msg/channel-debug.cjs.map +1 -1
- package/dist/common/msg/channel-debug.d.cts +1 -1
- package/dist/common/msg/channel-debug.d.mts +1 -1
- package/dist/common/msg/channel-debug.mjs +16 -1
- package/dist/common/msg/channel-debug.mjs.map +1 -1
- package/dist/common/msg/channel-local.cjs +28 -1
- package/dist/common/msg/channel-local.cjs.map +1 -1
- package/dist/common/msg/channel-local.d.cts +1 -1
- package/dist/common/msg/channel-local.d.mts +1 -1
- package/dist/common/msg/channel-local.mjs +26 -1
- package/dist/common/msg/channel-local.mjs.map +1 -1
- package/dist/common/msg/channel-resilient.cjs +63 -1
- package/dist/common/msg/channel-resilient.cjs.map +1 -1
- package/dist/common/msg/channel-resilient.d.cts +1 -1
- package/dist/common/msg/channel-resilient.d.mts +1 -1
- package/dist/common/msg/channel-resilient.mjs +62 -1
- package/dist/common/msg/channel-resilient.mjs.map +1 -1
- package/dist/common/msg/channel-wkwebview.cjs +35 -1
- package/dist/common/msg/channel-wkwebview.cjs.map +1 -1
- package/dist/common/msg/channel-wkwebview.d.cts +2 -1
- package/dist/common/msg/channel-wkwebview.d.mts +2 -1
- package/dist/common/msg/channel-wkwebview.mjs +34 -1
- package/dist/common/msg/channel-wkwebview.mjs.map +1 -1
- package/dist/common/msg/channel.cjs +23 -1
- package/dist/common/msg/channel.cjs.map +1 -1
- package/dist/common/msg/channel.d.cts +1 -1
- package/dist/common/msg/channel.d.mts +1 -1
- package/dist/common/msg/channel.mjs +22 -1
- package/dist/common/msg/channel.mjs.map +1 -1
- package/dist/common/msg/emitter.cjs +141 -1
- package/dist/common/msg/emitter.cjs.map +1 -1
- package/dist/common/msg/emitter.d.cts +1 -1
- package/dist/common/msg/emitter.d.mts +1 -1
- package/dist/common/msg/emitter.mjs +139 -1
- package/dist/common/msg/emitter.mjs.map +1 -1
- package/dist/common/msg/encoder.cjs +38 -1
- package/dist/common/msg/encoder.cjs.map +1 -1
- package/dist/common/msg/encoder.mjs +35 -1
- package/dist/common/msg/encoder.mjs.map +1 -1
- package/dist/common/msg/index.cjs +28 -1
- package/dist/common/msg/index.d.cts +1 -1
- package/dist/common/msg/index.d.mts +1 -1
- package/dist/common/msg/index.mjs +11 -1
- package/dist/common/msg/messages.cjs +135 -1
- package/dist/common/msg/messages.cjs.map +1 -1
- package/dist/common/msg/messages.d.cts +1 -1
- package/dist/common/msg/messages.d.mts +1 -1
- package/dist/common/msg/messages.mjs +133 -1
- package/dist/common/msg/messages.mjs.map +1 -1
- package/dist/common/msg/pipe.mjs +1 -1
- package/dist/common/msg/pubsub.cjs +78 -1
- package/dist/common/msg/pubsub.cjs.map +1 -1
- package/dist/common/msg/pubsub.d.cts +1 -1
- package/dist/common/msg/pubsub.d.mts +1 -1
- package/dist/common/msg/pubsub.mjs +76 -1
- package/dist/common/msg/pubsub.mjs.map +1 -1
- package/dist/common/msg/rpc.cjs +142 -1
- package/dist/common/msg/rpc.cjs.map +1 -1
- package/dist/common/msg/rpc.mjs +139 -1
- package/dist/common/msg/rpc.mjs.map +1 -1
- package/dist/common/network.cjs +129 -1
- package/dist/common/network.cjs.map +1 -1
- package/dist/common/network.mjs +122 -1
- package/dist/common/network.mjs.map +1 -1
- package/dist/common/platform.cjs +92 -1
- package/dist/common/platform.cjs.map +1 -1
- package/dist/common/platform.mjs +84 -1
- package/dist/common/platform.mjs.map +1 -1
- package/dist/common/schema/_sandbox/sandbox-inherit.mjs +1 -1
- package/dist/common/schema/_sandbox/sandbox.mjs +1 -1
- package/dist/common/schema/_sandbox/sandbox.xspec.mjs +1 -1
- package/dist/common/schema/export-json-schema.cjs +54 -1
- package/dist/common/schema/export-json-schema.cjs.map +1 -1
- package/dist/common/schema/export-json-schema.mjs +52 -1
- package/dist/common/schema/export-json-schema.mjs.map +1 -1
- package/dist/common/schema/export-swift.cjs +30 -2
- package/dist/common/schema/export-swift.cjs.map +1 -1
- package/dist/common/schema/export-swift.mjs +29 -2
- package/dist/common/schema/export-swift.mjs.map +1 -1
- package/dist/common/schema/export-typescript.cjs +20 -2
- package/dist/common/schema/export-typescript.cjs.map +1 -1
- package/dist/common/schema/export-typescript.mjs +19 -2
- package/dist/common/schema/export-typescript.mjs.map +1 -1
- package/dist/common/schema/index.cjs +55 -1
- package/dist/common/schema/index.mjs +12 -1
- package/dist/common/schema/parse-args.cjs +62 -2
- package/dist/common/schema/parse-args.cjs.map +1 -1
- package/dist/common/schema/parse-args.mjs +60 -2
- package/dist/common/schema/parse-args.mjs.map +1 -1
- package/dist/common/schema/parse-env.cjs +48 -3
- package/dist/common/schema/parse-env.cjs.map +1 -1
- package/dist/common/schema/parse-env.mjs +46 -3
- package/dist/common/schema/parse-env.mjs.map +1 -1
- package/dist/common/schema/parse-object.cjs +122 -1
- package/dist/common/schema/parse-object.cjs.map +1 -1
- package/dist/common/schema/parse-object.mjs +119 -1
- package/dist/common/schema/parse-object.mjs.map +1 -1
- package/dist/common/schema/schema-standard.mjs +1 -1
- package/dist/common/schema/schema.cjs +423 -1
- package/dist/common/schema/schema.cjs.map +1 -1
- package/dist/common/schema/schema.mjs +404 -1
- package/dist/common/schema/schema.mjs.map +1 -1
- package/dist/common/schema/serialize.cjs +109 -1
- package/dist/common/schema/serialize.cjs.map +1 -1
- package/dist/common/schema/serialize.mjs +107 -1
- package/dist/common/schema/serialize.mjs.map +1 -1
- package/dist/common/schema/type-test.mjs +1 -1
- package/dist/common/schema/utils.cjs +25 -1
- package/dist/common/schema/utils.cjs.map +1 -1
- package/dist/common/schema/utils.mjs +19 -1
- package/dist/common/schema/utils.mjs.map +1 -1
- package/dist/common/schema/z-collection.cjs +51 -1
- package/dist/common/schema/z-collection.mjs +27 -1
- package/dist/common/schema/z.cjs +9 -1
- package/dist/common/schema/z.mjs +3 -1
- package/dist/common/storage/index.cjs +4 -1
- package/dist/common/storage/index.mjs +3 -1
- package/dist/common/storage/memstorage.cjs +26 -1
- package/dist/common/storage/memstorage.cjs.map +1 -1
- package/dist/common/storage/memstorage.mjs +25 -1
- package/dist/common/storage/memstorage.mjs.map +1 -1
- package/dist/common/test.cjs +14 -1
- package/dist/common/test.cjs.map +1 -1
- package/dist/common/test.mjs +13 -1
- package/dist/common/test.mjs.map +1 -1
- package/dist/common/time.cjs +220 -1
- package/dist/common/time.cjs.map +1 -1
- package/dist/common/time.mjs +194 -1
- package/dist/common/time.mjs.map +1 -1
- package/dist/common/timeout.cjs +27 -1
- package/dist/common/timeout.cjs.map +1 -1
- package/dist/common/timeout.mjs +25 -1
- package/dist/common/timeout.mjs.map +1 -1
- package/dist/common/types.mjs +1 -1
- package/dist/common/utils.cjs +7 -1
- package/dist/common/utils.cjs.map +1 -1
- package/dist/common/utils.mjs +5 -1
- package/dist/common/utils.mjs.map +1 -1
- package/dist/common/uuid.cjs +307 -1
- package/dist/common/uuid.cjs.map +1 -1
- package/dist/common/uuid.mjs +284 -1
- package/dist/common/uuid.mjs.map +1 -1
- package/dist/{index-DHXVOH8h.d.cts → index-CFkMqHvX.d.cts} +1 -2
- package/dist/{index-DMaPyx9O.d.mts → index-C_3Y_s6f.d.mts} +1 -2
- package/dist/index.all.cjs +641 -1
- package/dist/index.all.d.cts +1 -1
- package/dist/index.all.d.mts +1 -1
- package/dist/index.all.mjs +113 -1
- package/dist/index.browser.cjs +576 -1
- package/dist/index.browser.d.cts +1 -1
- package/dist/index.browser.d.mts +1 -1
- package/dist/index.browser.mjs +98 -1
- package/dist/index.jsr.cjs +57 -1
- package/dist/index.jsr.mjs +6 -1
- package/dist/index.node.cjs +628 -1
- package/dist/index.node.d.cts +1 -1
- package/dist/index.node.d.mts +1 -1
- package/dist/index.node.mjs +106 -1
- package/dist/node/args.cjs +56 -1
- package/dist/node/args.cjs.map +1 -1
- package/dist/node/args.mjs +53 -1
- package/dist/node/args.mjs.map +1 -1
- package/dist/node/clipboard.cjs +18 -1
- package/dist/node/clipboard.cjs.map +1 -1
- package/dist/node/clipboard.mjs +16 -1
- package/dist/node/clipboard.mjs.map +1 -1
- package/dist/node/crypto.cjs +28 -1
- package/dist/node/crypto.cjs.map +1 -1
- package/dist/node/crypto.mjs +24 -1
- package/dist/node/crypto.mjs.map +1 -1
- package/dist/node/env.cjs +100 -4
- package/dist/node/env.cjs.map +1 -1
- package/dist/node/env.mjs +90 -4
- package/dist/node/env.mjs.map +1 -1
- package/dist/node/files-async.cjs +66 -1
- package/dist/node/files-async.cjs.map +1 -1
- package/dist/node/files-async.mjs +60 -1
- package/dist/node/files-async.mjs.map +1 -1
- package/dist/node/files.cjs +52 -1
- package/dist/node/files.cjs.map +1 -1
- package/dist/node/files.mjs +46 -1
- package/dist/node/files.mjs.map +1 -1
- package/dist/node/filestorage.cjs +100 -1
- package/dist/node/filestorage.cjs.map +1 -1
- package/dist/node/filestorage.mjs +97 -1
- package/dist/node/filestorage.mjs.map +1 -1
- package/dist/node/fs.cjs +119 -1
- package/dist/node/fs.cjs.map +1 -1
- package/dist/node/fs.mjs +101 -1
- package/dist/node/fs.mjs.map +1 -1
- package/dist/node/glob.cjs +75 -1
- package/dist/node/glob.cjs.map +1 -1
- package/dist/node/glob.mjs +73 -1
- package/dist/node/glob.mjs.map +1 -1
- package/dist/node/index.cjs +66 -1
- package/dist/node/index.mjs +16 -1
- package/dist/node/log/index.cjs +20 -1
- package/dist/node/log/index.mjs +7 -1
- package/dist/node/log/log-context-node.cjs +39 -1
- package/dist/node/log/log-context-node.cjs.map +1 -1
- package/dist/node/log/log-context-node.mjs +35 -1
- package/dist/node/log/log-context-node.mjs.map +1 -1
- package/dist/node/log/log-file-rotation.cjs +71 -1
- package/dist/node/log/log-file-rotation.cjs.map +1 -1
- package/dist/node/log/log-file-rotation.mjs +68 -1
- package/dist/node/log/log-file-rotation.mjs.map +1 -1
- package/dist/node/log/log-file.cjs +57 -1
- package/dist/node/log/log-file.cjs.map +1 -1
- package/dist/node/log/log-file.mjs +54 -1
- package/dist/node/log/log-file.mjs.map +1 -1
- package/dist/node/log/log-node.cjs +162 -1
- package/dist/node/log/log-node.cjs.map +1 -1
- package/dist/node/log/log-node.mjs +155 -1
- package/dist/node/log/log-node.mjs.map +1 -1
- package/dist/node/log/log-rotation.cjs +543 -3
- package/dist/node/log/log-rotation.cjs.map +1 -1
- package/dist/node/log/log-rotation.mjs +538 -3
- package/dist/node/log/log-rotation.mjs.map +1 -1
- package/dist/node/log/log-util.cjs +69 -3
- package/dist/node/log/log-util.cjs.map +1 -1
- package/dist/node/log/log-util.mjs +63 -3
- package/dist/node/log/log-util.mjs.map +1 -1
- package/dist/node/open-browser.cjs +20 -1
- package/dist/node/open-browser.cjs.map +1 -1
- package/dist/node/open-browser.mjs +18 -1
- package/dist/node/open-browser.mjs.map +1 -1
- package/package.json +15 -15
- package/src/common/schema/README.md +247 -66
- package/src/eslint-defaults.js +4 -0
- package/src/index.spec.ts +6 -6
- package/dist/bin-Ce3i6ABn.cjs +0 -3
- package/dist/bin-SPdenYkw.mjs +0 -3
- package/dist/chunk-0Lt9GpW0.mjs +0 -1
- package/dist/chunk-D-qHiVGv.cjs +0 -1
- package/src/common/schema/README-SCHEMA.md +0 -0
|
@@ -1,2 +1,182 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_common_exec_promise = require('./promise.cjs');
|
|
3
|
+
const require_common_dispose_defer = require('../dispose-defer.cjs');
|
|
4
|
+
const require_common_msg_emitter = require('../msg/emitter.cjs');
|
|
5
|
+
const require_common_uuid = require('../uuid.cjs');
|
|
6
|
+
const require_common_exec_progress = require('./progress.cjs');
|
|
7
|
+
|
|
8
|
+
//#region src/common/exec/pool.ts
|
|
9
|
+
function usePool(config = {}) {
|
|
10
|
+
const { maxParallel = 3, name = require_common_uuid.uname("pool"), idConflictResolution = "memoize" } = config;
|
|
11
|
+
const events = new require_common_msg_emitter.Emitter();
|
|
12
|
+
const dispose = require_common_dispose_defer.useDispose();
|
|
13
|
+
dispose.add(cancelAll);
|
|
14
|
+
const progress = new require_common_exec_progress.Progress({ name });
|
|
15
|
+
progress.on("progressCancelled", cancelAll);
|
|
16
|
+
let countMax = 0;
|
|
17
|
+
let countResolved = 0;
|
|
18
|
+
let currentParallel = 0;
|
|
19
|
+
let priority = 0;
|
|
20
|
+
const tasks = {};
|
|
21
|
+
async function waitFinishAll() {
|
|
22
|
+
if (countMax > 0) {
|
|
23
|
+
const [promise, resolve] = require_common_exec_promise.createPromise();
|
|
24
|
+
events.once("didFinish", resolve);
|
|
25
|
+
return promise;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function cleanupFinished() {
|
|
29
|
+
for (const id of Object.keys(tasks)) if (tasks[id].state === "finished") {
|
|
30
|
+
await tasks[id].progress.dispose();
|
|
31
|
+
delete tasks[id];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function didFinish() {
|
|
35
|
+
events.emit("didFinish");
|
|
36
|
+
countMax = 0;
|
|
37
|
+
countResolved = 0;
|
|
38
|
+
cleanupFinished();
|
|
39
|
+
progress.reset();
|
|
40
|
+
}
|
|
41
|
+
function didUpdate() {
|
|
42
|
+
let presentMax = 0;
|
|
43
|
+
let presentResolved = 0;
|
|
44
|
+
for (const { max, resolved, state } of Object.values(tasks)) {
|
|
45
|
+
presentMax += max;
|
|
46
|
+
presentResolved += state === "finished" ? max : Math.min(max, resolved);
|
|
47
|
+
}
|
|
48
|
+
events.emit("didUpdate", countMax, countResolved, presentMax, presentResolved);
|
|
49
|
+
}
|
|
50
|
+
function performNext() {
|
|
51
|
+
didUpdate();
|
|
52
|
+
if (countMax > 0 && countMax === countResolved) didFinish();
|
|
53
|
+
if (currentParallel >= maxParallel) return;
|
|
54
|
+
const waitingTasks = Object.values(tasks).filter((t) => t.state === "waiting");
|
|
55
|
+
if (waitingTasks.length > 0) {
|
|
56
|
+
let taskInfo;
|
|
57
|
+
for (const t of waitingTasks) {
|
|
58
|
+
if (t.group != null && Object.values(tasks).some((tt) => tt.state === "running" && tt.id !== t.id && tt.group === t.group)) continue;
|
|
59
|
+
if (taskInfo == null || t.priority < taskInfo.priority) taskInfo = t;
|
|
60
|
+
}
|
|
61
|
+
if (taskInfo != null) {
|
|
62
|
+
const id = taskInfo.id;
|
|
63
|
+
const done = taskInfo.done;
|
|
64
|
+
taskInfo.state = "running";
|
|
65
|
+
++currentParallel;
|
|
66
|
+
events.emit("didStart", id);
|
|
67
|
+
const taskFinished = (result) => {
|
|
68
|
+
if (taskInfo) {
|
|
69
|
+
taskInfo.result = result;
|
|
70
|
+
taskInfo.state = "finished";
|
|
71
|
+
taskInfo.resolved = taskInfo.max;
|
|
72
|
+
taskInfo.progress?.setCompleted();
|
|
73
|
+
}
|
|
74
|
+
--currentParallel;
|
|
75
|
+
++countResolved;
|
|
76
|
+
performNext();
|
|
77
|
+
};
|
|
78
|
+
taskInfo.task(taskInfo).then((r) => {
|
|
79
|
+
done(r);
|
|
80
|
+
events.emit("didResolve", id, r);
|
|
81
|
+
taskFinished(r);
|
|
82
|
+
}).catch((err) => {
|
|
83
|
+
done();
|
|
84
|
+
events.emit("didReject", id, err);
|
|
85
|
+
taskFinished();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function cancel(id) {
|
|
91
|
+
const taskInfo = tasks[id];
|
|
92
|
+
if (taskInfo && taskInfo.state === "waiting") {
|
|
93
|
+
tasks[id].state = "finished";
|
|
94
|
+
++countResolved;
|
|
95
|
+
events.emit("didCancel", id);
|
|
96
|
+
tasks[id].progress.dispose();
|
|
97
|
+
didUpdate();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function cancelAll() {
|
|
101
|
+
Object.keys(tasks).forEach(cancel);
|
|
102
|
+
}
|
|
103
|
+
function hasById(id) {
|
|
104
|
+
return tasks[id] != null;
|
|
105
|
+
}
|
|
106
|
+
function enqueue(task, config = {}) {
|
|
107
|
+
let done;
|
|
108
|
+
const promise = new Promise((resolve) => done = resolve);
|
|
109
|
+
const id = config.id ?? require_common_uuid.uuid();
|
|
110
|
+
if (tasks[id] != null) {
|
|
111
|
+
const resolution = config.idConflictResolution ?? idConflictResolution;
|
|
112
|
+
if (resolution === "replace") cancel(id);
|
|
113
|
+
else if (resolution === "memoize" || resolution === "prioritize") {
|
|
114
|
+
const runningTask = tasks[id];
|
|
115
|
+
if (resolution === "prioritize") runningTask.priority = ++priority;
|
|
116
|
+
return {
|
|
117
|
+
id,
|
|
118
|
+
promise: (async () => {
|
|
119
|
+
if (runningTask.state === "finished") return tasks[id].result;
|
|
120
|
+
})(),
|
|
121
|
+
dispose: () => cancel(id),
|
|
122
|
+
cancel: () => cancel(id)
|
|
123
|
+
};
|
|
124
|
+
} else throw new Error(`Pool task with id=${id} already exists!`);
|
|
125
|
+
}
|
|
126
|
+
const taskProgress = new require_common_exec_progress.Progress({
|
|
127
|
+
name: id,
|
|
128
|
+
totalUnits: config.max ?? 1,
|
|
129
|
+
completeUnits: config.resolved ?? 0
|
|
130
|
+
});
|
|
131
|
+
progress.addChild(taskProgress);
|
|
132
|
+
tasks[id] = {
|
|
133
|
+
id,
|
|
134
|
+
task,
|
|
135
|
+
priority: ++priority,
|
|
136
|
+
group: config.group,
|
|
137
|
+
state: "waiting",
|
|
138
|
+
max: config.max ?? 1,
|
|
139
|
+
resolved: config.resolved ?? 0,
|
|
140
|
+
done,
|
|
141
|
+
payload: config.payload,
|
|
142
|
+
progress: taskProgress,
|
|
143
|
+
setMax(units) {
|
|
144
|
+
taskProgress.setTotalUnits(units);
|
|
145
|
+
tasks[id].max = units;
|
|
146
|
+
didUpdate();
|
|
147
|
+
},
|
|
148
|
+
setResolved(units) {
|
|
149
|
+
taskProgress.setCompletetedUnits(units);
|
|
150
|
+
tasks[id].resolved = units;
|
|
151
|
+
didUpdate();
|
|
152
|
+
},
|
|
153
|
+
incResolved(inc = 1) {
|
|
154
|
+
taskProgress.incCompletedUnits(inc);
|
|
155
|
+
tasks[id].resolved += inc;
|
|
156
|
+
didUpdate();
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
++countMax;
|
|
160
|
+
performNext();
|
|
161
|
+
return {
|
|
162
|
+
id,
|
|
163
|
+
promise,
|
|
164
|
+
dispose: () => cancel(id),
|
|
165
|
+
cancel: () => cancel(id)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
events,
|
|
170
|
+
cancel,
|
|
171
|
+
cancelAll,
|
|
172
|
+
hasById,
|
|
173
|
+
progress,
|
|
174
|
+
enqueue,
|
|
175
|
+
dispose,
|
|
176
|
+
waitFinishAll
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
//#endregion
|
|
181
|
+
exports.usePool = usePool;
|
|
2
182
|
//# sourceMappingURL=pool.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pool.cjs","names":["uname","Emitter","useDispose","Progress","createPromise","uuid"],"sources":["../../../src/common/exec/pool.ts"],"sourcesContent":["import { useDispose } from '../dispose-defer'\nimport { Emitter } from '../msg/emitter'\nimport { uname, uuid } from '../uuid'\nimport { Progress } from './progress'\nimport { createPromise } from './promise'\n\nexport type PoolTaskIdConflictResolution = 'replace' | 'memoize' | 'prioritize' | 'error'\n\n// export enum PoolTaskIdConflictResolution {\n// /**\n// * Tasks with same `id` are replaced. Newest wins.\n// */\n// replace = 0,\n\n// /**\n// * Task with same `id` will continue to run. Reference is returned with option to cancel.\n// * Named \"memoize\" because the result of the task should always be the same for the same `id`,\n// * like e.g. a download.\n// */\n// memoize = 1,\n\n// /** Like memoize, but try to put on top of the list */\n// prioritize = 2,\n\n// /**\n// * Tasks with same `id` throw error\n// */\n// error = 3,\n\n// }\n\nexport interface PoolConfig {\n name?: string\n maxParallel?: number\n idConflictResolution?: PoolTaskIdConflictResolution\n}\n\nexport type PoolTaskFn<T = any> = (taskInfo: PoolTask<T>) => Promise<T>\n\nexport type PoolTaskState = 'waiting' | 'running' | 'finished'\n\n/** Task */\nexport interface PoolTask<T> {\n readonly id: string\n readonly task: PoolTaskFn<T>\n readonly done: (result?: any) => void\n readonly setMax: (max: number) => void\n readonly setResolved: (resolved: number) => void\n readonly incResolved: (inc?: number) => void\n state: PoolTaskState\n priority: number\n /** Same groups are executed only one at a time */\n group?: string\n\n progress: Progress\n max: number\n resolved: number\n\n result?: T\n payload?: unknown\n}\n\nexport interface PoolTaskEvents {\n didUpdate: (\n max: number,\n resolved: number,\n presentMax: number,\n presentResolved: number,\n ) => void\n didStart: (id: string) => void\n didCancel: (id: string) => void\n didFinish: () => void\n didResolve: (id: string, value: any) => void\n didReject: (id: string, error: any) => void\n}\n\n// todo: barrier\n// todo: dependents\n\nexport function usePool<T = any>(config: PoolConfig = {}) {\n const {\n maxParallel = 3,\n name = uname('pool'),\n idConflictResolution = 'memoize',\n } = config\n\n const events = new Emitter<PoolTaskEvents>()\n\n const dispose = useDispose()\n dispose.add(cancelAll)\n\n const progress = new Progress({ name })\n\n progress.on('progressCancelled', cancelAll)\n\n let countMax = 0\n let countResolved = 0\n let currentParallel = 0\n let priority = 0\n const tasks: Record<string, PoolTask<T>> = {}\n\n // const [allFinishedPromise, allFinishedResolve] = createPromise()\n\n async function waitFinishAll() {\n if (countMax > 0) {\n const [promise, resolve] = createPromise()\n events.once('didFinish', resolve)\n return promise\n }\n }\n\n async function cleanupFinished() {\n for (const id of Object.keys(tasks)) {\n const task = tasks[id]\n if (task.state === 'finished') {\n await tasks[id].progress.dispose()\n delete tasks[id]\n }\n }\n }\n\n function didFinish() {\n void events.emit('didFinish')\n // allFinishedResolve(countMax)\n countMax = 0\n countResolved = 0\n void cleanupFinished()\n progress.reset()\n }\n\n function didUpdate() {\n let presentMax = 0\n let presentResolved = 0\n for (const { max, resolved, state } of Object.values(tasks)) {\n presentMax += max\n presentResolved += state === 'finished' ? max : Math.min(max, resolved)\n }\n void events.emit(\n 'didUpdate',\n countMax,\n countResolved,\n presentMax,\n presentResolved,\n )\n }\n\n function performNext() {\n didUpdate()\n if (countMax > 0 && countMax === countResolved)\n didFinish()\n if (currentParallel >= maxParallel)\n return\n const waitingTasks = Object.values(tasks).filter(\n t => t.state === 'waiting',\n )\n if (waitingTasks.length > 0) {\n let taskInfo: PoolTask<T> | undefined\n for (const t of waitingTasks) {\n // Skip task if one of same group is running.\n // Forces serialized execution for subgroup of tasks.\n if (\n t.group != null\n && Object.values(tasks).some(\n tt =>\n tt.state === 'running'\n && tt.id !== t.id\n && tt.group === t.group,\n )\n ) {\n continue\n }\n\n // fifo\n if (taskInfo == null || t.priority < taskInfo.priority)\n taskInfo = t\n }\n if (taskInfo != null) {\n const id = taskInfo.id\n const done = taskInfo.done\n taskInfo.state = 'running'\n ++currentParallel\n void events.emit('didStart', id)\n\n const taskFinished = (result?: T) => {\n if (taskInfo) {\n taskInfo.result = result\n taskInfo.state = 'finished'\n taskInfo.resolved = taskInfo.max\n taskInfo.progress?.setCompleted()\n // void taskInfo.progress.dispose()\n }\n --currentParallel\n ++countResolved\n performNext()\n }\n\n taskInfo\n .task(taskInfo)\n .then((r) => {\n done(r)\n void events.emit('didResolve', id, r)\n taskFinished(r)\n })\n .catch((err) => {\n done()\n void events.emit('didReject', id, err)\n taskFinished()\n })\n }\n }\n }\n\n function cancel(id: string) {\n const taskInfo = tasks[id]\n if (taskInfo && taskInfo.state === 'waiting') {\n tasks[id].state = 'finished'\n ++countResolved\n void events.emit('didCancel', id)\n void tasks[id].progress.dispose()\n didUpdate()\n }\n }\n\n function cancelAll() {\n Object.keys(tasks).forEach(cancel)\n // progress.dispose()\n }\n\n function hasById(id: string) {\n return tasks[id] != null\n }\n\n function enqueue<P>(\n task: PoolTaskFn<T>,\n config: {\n id?: string\n max?: number\n resolved?: number\n group?: string\n idConflictResolution?: PoolTaskIdConflictResolution\n payload?: P\n } = {},\n ) {\n let done: any\n const promise: Promise<any> = new Promise(resolve => (done = resolve))\n const id = config.id ?? uuid()\n\n if (tasks[id] != null) {\n const resolution = config.idConflictResolution ?? idConflictResolution\n\n if (resolution === 'replace') {\n cancel(id)\n }\n else if (resolution === 'memoize' || resolution === 'prioritize') {\n const runningTask = tasks[id]\n\n if (resolution === 'prioritize')\n runningTask.priority = ++priority\n\n return {\n id,\n promise: (async () => {\n if (runningTask.state === 'finished')\n return tasks[id].result\n\n // todo: wait for task to finish\n })(),\n dispose: () => cancel(id),\n cancel: () => cancel(id),\n }\n }\n else {\n throw new Error(`Pool task with id=${id} already exists!`)\n }\n }\n\n const taskProgress = new Progress({\n name: id,\n totalUnits: config.max ?? 1,\n completeUnits: config.resolved ?? 0,\n })\n\n progress.addChild(taskProgress)\n\n tasks[id] = {\n id,\n task,\n priority: ++priority,\n group: config.group,\n state: 'waiting',\n max: config.max ?? 1,\n resolved: config.resolved ?? 0,\n done,\n payload: config.payload,\n progress: taskProgress,\n\n /** @deprecated should use `.progress` */\n setMax(units) {\n taskProgress.setTotalUnits(units)\n tasks[id].max = units\n didUpdate()\n },\n\n /** @deprecated should use `.progress` */\n setResolved(units) {\n taskProgress.setCompletetedUnits(units)\n tasks[id].resolved = units\n didUpdate()\n },\n\n /** @deprecated should use `.progress` */\n incResolved(inc = 1) {\n taskProgress.incCompletedUnits(inc)\n tasks[id].resolved += inc\n didUpdate()\n },\n }\n ++countMax\n performNext()\n\n return {\n id,\n promise,\n dispose: () => cancel(id),\n cancel: () => cancel(id),\n }\n }\n\n return {\n events,\n cancel,\n cancelAll,\n hasById,\n progress,\n enqueue,\n dispose,\n waitFinishAll,\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pool.cjs","names":["uname","Emitter","useDispose","Progress","createPromise","uuid"],"sources":["../../../src/common/exec/pool.ts"],"sourcesContent":["import { useDispose } from '../dispose-defer'\nimport { Emitter } from '../msg/emitter'\nimport { uname, uuid } from '../uuid'\nimport { Progress } from './progress'\nimport { createPromise } from './promise'\n\nexport type PoolTaskIdConflictResolution = 'replace' | 'memoize' | 'prioritize' | 'error'\n\n// export enum PoolTaskIdConflictResolution {\n// /**\n// * Tasks with same `id` are replaced. Newest wins.\n// */\n// replace = 0,\n\n// /**\n// * Task with same `id` will continue to run. Reference is returned with option to cancel.\n// * Named \"memoize\" because the result of the task should always be the same for the same `id`,\n// * like e.g. a download.\n// */\n// memoize = 1,\n\n// /** Like memoize, but try to put on top of the list */\n// prioritize = 2,\n\n// /**\n// * Tasks with same `id` throw error\n// */\n// error = 3,\n\n// }\n\nexport interface PoolConfig {\n name?: string\n maxParallel?: number\n idConflictResolution?: PoolTaskIdConflictResolution\n}\n\nexport type PoolTaskFn<T = any> = (taskInfo: PoolTask<T>) => Promise<T>\n\nexport type PoolTaskState = 'waiting' | 'running' | 'finished'\n\n/** Task */\nexport interface PoolTask<T> {\n readonly id: string\n readonly task: PoolTaskFn<T>\n readonly done: (result?: any) => void\n readonly setMax: (max: number) => void\n readonly setResolved: (resolved: number) => void\n readonly incResolved: (inc?: number) => void\n state: PoolTaskState\n priority: number\n /** Same groups are executed only one at a time */\n group?: string\n\n progress: Progress\n max: number\n resolved: number\n\n result?: T\n payload?: unknown\n}\n\nexport interface PoolTaskEvents {\n didUpdate: (\n max: number,\n resolved: number,\n presentMax: number,\n presentResolved: number,\n ) => void\n didStart: (id: string) => void\n didCancel: (id: string) => void\n didFinish: () => void\n didResolve: (id: string, value: any) => void\n didReject: (id: string, error: any) => void\n}\n\n// todo: barrier\n// todo: dependents\n\nexport function usePool<T = any>(config: PoolConfig = {}) {\n const {\n maxParallel = 3,\n name = uname('pool'),\n idConflictResolution = 'memoize',\n } = config\n\n const events = new Emitter<PoolTaskEvents>()\n\n const dispose = useDispose()\n dispose.add(cancelAll)\n\n const progress = new Progress({ name })\n\n progress.on('progressCancelled', cancelAll)\n\n let countMax = 0\n let countResolved = 0\n let currentParallel = 0\n let priority = 0\n const tasks: Record<string, PoolTask<T>> = {}\n\n // const [allFinishedPromise, allFinishedResolve] = createPromise()\n\n async function waitFinishAll() {\n if (countMax > 0) {\n const [promise, resolve] = createPromise()\n events.once('didFinish', resolve)\n return promise\n }\n }\n\n async function cleanupFinished() {\n for (const id of Object.keys(tasks)) {\n const task = tasks[id]\n if (task.state === 'finished') {\n await tasks[id].progress.dispose()\n delete tasks[id]\n }\n }\n }\n\n function didFinish() {\n void events.emit('didFinish')\n // allFinishedResolve(countMax)\n countMax = 0\n countResolved = 0\n void cleanupFinished()\n progress.reset()\n }\n\n function didUpdate() {\n let presentMax = 0\n let presentResolved = 0\n for (const { max, resolved, state } of Object.values(tasks)) {\n presentMax += max\n presentResolved += state === 'finished' ? max : Math.min(max, resolved)\n }\n void events.emit(\n 'didUpdate',\n countMax,\n countResolved,\n presentMax,\n presentResolved,\n )\n }\n\n function performNext() {\n didUpdate()\n if (countMax > 0 && countMax === countResolved)\n didFinish()\n if (currentParallel >= maxParallel)\n return\n const waitingTasks = Object.values(tasks).filter(\n t => t.state === 'waiting',\n )\n if (waitingTasks.length > 0) {\n let taskInfo: PoolTask<T> | undefined\n for (const t of waitingTasks) {\n // Skip task if one of same group is running.\n // Forces serialized execution for subgroup of tasks.\n if (\n t.group != null\n && Object.values(tasks).some(\n tt =>\n tt.state === 'running'\n && tt.id !== t.id\n && tt.group === t.group,\n )\n ) {\n continue\n }\n\n // fifo\n if (taskInfo == null || t.priority < taskInfo.priority)\n taskInfo = t\n }\n if (taskInfo != null) {\n const id = taskInfo.id\n const done = taskInfo.done\n taskInfo.state = 'running'\n ++currentParallel\n void events.emit('didStart', id)\n\n const taskFinished = (result?: T) => {\n if (taskInfo) {\n taskInfo.result = result\n taskInfo.state = 'finished'\n taskInfo.resolved = taskInfo.max\n taskInfo.progress?.setCompleted()\n // void taskInfo.progress.dispose()\n }\n --currentParallel\n ++countResolved\n performNext()\n }\n\n taskInfo\n .task(taskInfo)\n .then((r) => {\n done(r)\n void events.emit('didResolve', id, r)\n taskFinished(r)\n })\n .catch((err) => {\n done()\n void events.emit('didReject', id, err)\n taskFinished()\n })\n }\n }\n }\n\n function cancel(id: string) {\n const taskInfo = tasks[id]\n if (taskInfo && taskInfo.state === 'waiting') {\n tasks[id].state = 'finished'\n ++countResolved\n void events.emit('didCancel', id)\n void tasks[id].progress.dispose()\n didUpdate()\n }\n }\n\n function cancelAll() {\n Object.keys(tasks).forEach(cancel)\n // progress.dispose()\n }\n\n function hasById(id: string) {\n return tasks[id] != null\n }\n\n function enqueue<P>(\n task: PoolTaskFn<T>,\n config: {\n id?: string\n max?: number\n resolved?: number\n group?: string\n idConflictResolution?: PoolTaskIdConflictResolution\n payload?: P\n } = {},\n ) {\n let done: any\n const promise: Promise<any> = new Promise(resolve => (done = resolve))\n const id = config.id ?? uuid()\n\n if (tasks[id] != null) {\n const resolution = config.idConflictResolution ?? idConflictResolution\n\n if (resolution === 'replace') {\n cancel(id)\n }\n else if (resolution === 'memoize' || resolution === 'prioritize') {\n const runningTask = tasks[id]\n\n if (resolution === 'prioritize')\n runningTask.priority = ++priority\n\n return {\n id,\n promise: (async () => {\n if (runningTask.state === 'finished')\n return tasks[id].result\n\n // todo: wait for task to finish\n })(),\n dispose: () => cancel(id),\n cancel: () => cancel(id),\n }\n }\n else {\n throw new Error(`Pool task with id=${id} already exists!`)\n }\n }\n\n const taskProgress = new Progress({\n name: id,\n totalUnits: config.max ?? 1,\n completeUnits: config.resolved ?? 0,\n })\n\n progress.addChild(taskProgress)\n\n tasks[id] = {\n id,\n task,\n priority: ++priority,\n group: config.group,\n state: 'waiting',\n max: config.max ?? 1,\n resolved: config.resolved ?? 0,\n done,\n payload: config.payload,\n progress: taskProgress,\n\n /** @deprecated should use `.progress` */\n setMax(units) {\n taskProgress.setTotalUnits(units)\n tasks[id].max = units\n didUpdate()\n },\n\n /** @deprecated should use `.progress` */\n setResolved(units) {\n taskProgress.setCompletetedUnits(units)\n tasks[id].resolved = units\n didUpdate()\n },\n\n /** @deprecated should use `.progress` */\n incResolved(inc = 1) {\n taskProgress.incCompletedUnits(inc)\n tasks[id].resolved += inc\n didUpdate()\n },\n }\n ++countMax\n performNext()\n\n return {\n id,\n promise,\n dispose: () => cancel(id),\n cancel: () => cancel(id),\n }\n }\n\n return {\n events,\n cancel,\n cancelAll,\n hasById,\n progress,\n enqueue,\n dispose,\n waitFinishAll,\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as PoolTask, c as PoolTaskIdConflictResolution, i as PoolConfig, l as PoolTaskState, o as PoolTaskEvents, s as PoolTaskFn, u as usePool } from "../../index-
|
|
1
|
+
import { a as PoolTask, c as PoolTaskIdConflictResolution, i as PoolConfig, l as PoolTaskState, o as PoolTaskEvents, s as PoolTaskFn, u as usePool } from "../../index-CFkMqHvX.cjs";
|
|
2
2
|
export { PoolConfig, PoolTask, PoolTaskEvents, PoolTaskFn, PoolTaskIdConflictResolution, PoolTaskState, usePool };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as PoolTask, c as PoolTaskIdConflictResolution, i as PoolConfig, l as PoolTaskState, o as PoolTaskEvents, s as PoolTaskFn, u as usePool } from "../../index-
|
|
1
|
+
import { a as PoolTask, c as PoolTaskIdConflictResolution, i as PoolConfig, l as PoolTaskState, o as PoolTaskEvents, s as PoolTaskFn, u as usePool } from "../../index-C_3Y_s6f.mjs";
|
|
2
2
|
export { PoolConfig, PoolTask, PoolTaskEvents, PoolTaskFn, PoolTaskIdConflictResolution, PoolTaskState, usePool };
|
|
@@ -1,2 +1,181 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createPromise } from "./promise.mjs";
|
|
2
|
+
import { useDispose } from "../dispose-defer.mjs";
|
|
3
|
+
import { Emitter } from "../msg/emitter.mjs";
|
|
4
|
+
import { uname, uuid } from "../uuid.mjs";
|
|
5
|
+
import { Progress } from "./progress.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/common/exec/pool.ts
|
|
8
|
+
function usePool(config = {}) {
|
|
9
|
+
const { maxParallel = 3, name = uname("pool"), idConflictResolution = "memoize" } = config;
|
|
10
|
+
const events = new Emitter();
|
|
11
|
+
const dispose = useDispose();
|
|
12
|
+
dispose.add(cancelAll);
|
|
13
|
+
const progress = new Progress({ name });
|
|
14
|
+
progress.on("progressCancelled", cancelAll);
|
|
15
|
+
let countMax = 0;
|
|
16
|
+
let countResolved = 0;
|
|
17
|
+
let currentParallel = 0;
|
|
18
|
+
let priority = 0;
|
|
19
|
+
const tasks = {};
|
|
20
|
+
async function waitFinishAll() {
|
|
21
|
+
if (countMax > 0) {
|
|
22
|
+
const [promise, resolve] = createPromise();
|
|
23
|
+
events.once("didFinish", resolve);
|
|
24
|
+
return promise;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function cleanupFinished() {
|
|
28
|
+
for (const id of Object.keys(tasks)) if (tasks[id].state === "finished") {
|
|
29
|
+
await tasks[id].progress.dispose();
|
|
30
|
+
delete tasks[id];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function didFinish() {
|
|
34
|
+
events.emit("didFinish");
|
|
35
|
+
countMax = 0;
|
|
36
|
+
countResolved = 0;
|
|
37
|
+
cleanupFinished();
|
|
38
|
+
progress.reset();
|
|
39
|
+
}
|
|
40
|
+
function didUpdate() {
|
|
41
|
+
let presentMax = 0;
|
|
42
|
+
let presentResolved = 0;
|
|
43
|
+
for (const { max, resolved, state } of Object.values(tasks)) {
|
|
44
|
+
presentMax += max;
|
|
45
|
+
presentResolved += state === "finished" ? max : Math.min(max, resolved);
|
|
46
|
+
}
|
|
47
|
+
events.emit("didUpdate", countMax, countResolved, presentMax, presentResolved);
|
|
48
|
+
}
|
|
49
|
+
function performNext() {
|
|
50
|
+
didUpdate();
|
|
51
|
+
if (countMax > 0 && countMax === countResolved) didFinish();
|
|
52
|
+
if (currentParallel >= maxParallel) return;
|
|
53
|
+
const waitingTasks = Object.values(tasks).filter((t) => t.state === "waiting");
|
|
54
|
+
if (waitingTasks.length > 0) {
|
|
55
|
+
let taskInfo;
|
|
56
|
+
for (const t of waitingTasks) {
|
|
57
|
+
if (t.group != null && Object.values(tasks).some((tt) => tt.state === "running" && tt.id !== t.id && tt.group === t.group)) continue;
|
|
58
|
+
if (taskInfo == null || t.priority < taskInfo.priority) taskInfo = t;
|
|
59
|
+
}
|
|
60
|
+
if (taskInfo != null) {
|
|
61
|
+
const id = taskInfo.id;
|
|
62
|
+
const done = taskInfo.done;
|
|
63
|
+
taskInfo.state = "running";
|
|
64
|
+
++currentParallel;
|
|
65
|
+
events.emit("didStart", id);
|
|
66
|
+
const taskFinished = (result) => {
|
|
67
|
+
if (taskInfo) {
|
|
68
|
+
taskInfo.result = result;
|
|
69
|
+
taskInfo.state = "finished";
|
|
70
|
+
taskInfo.resolved = taskInfo.max;
|
|
71
|
+
taskInfo.progress?.setCompleted();
|
|
72
|
+
}
|
|
73
|
+
--currentParallel;
|
|
74
|
+
++countResolved;
|
|
75
|
+
performNext();
|
|
76
|
+
};
|
|
77
|
+
taskInfo.task(taskInfo).then((r) => {
|
|
78
|
+
done(r);
|
|
79
|
+
events.emit("didResolve", id, r);
|
|
80
|
+
taskFinished(r);
|
|
81
|
+
}).catch((err) => {
|
|
82
|
+
done();
|
|
83
|
+
events.emit("didReject", id, err);
|
|
84
|
+
taskFinished();
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function cancel(id) {
|
|
90
|
+
const taskInfo = tasks[id];
|
|
91
|
+
if (taskInfo && taskInfo.state === "waiting") {
|
|
92
|
+
tasks[id].state = "finished";
|
|
93
|
+
++countResolved;
|
|
94
|
+
events.emit("didCancel", id);
|
|
95
|
+
tasks[id].progress.dispose();
|
|
96
|
+
didUpdate();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function cancelAll() {
|
|
100
|
+
Object.keys(tasks).forEach(cancel);
|
|
101
|
+
}
|
|
102
|
+
function hasById(id) {
|
|
103
|
+
return tasks[id] != null;
|
|
104
|
+
}
|
|
105
|
+
function enqueue(task, config = {}) {
|
|
106
|
+
let done;
|
|
107
|
+
const promise = new Promise((resolve) => done = resolve);
|
|
108
|
+
const id = config.id ?? uuid();
|
|
109
|
+
if (tasks[id] != null) {
|
|
110
|
+
const resolution = config.idConflictResolution ?? idConflictResolution;
|
|
111
|
+
if (resolution === "replace") cancel(id);
|
|
112
|
+
else if (resolution === "memoize" || resolution === "prioritize") {
|
|
113
|
+
const runningTask = tasks[id];
|
|
114
|
+
if (resolution === "prioritize") runningTask.priority = ++priority;
|
|
115
|
+
return {
|
|
116
|
+
id,
|
|
117
|
+
promise: (async () => {
|
|
118
|
+
if (runningTask.state === "finished") return tasks[id].result;
|
|
119
|
+
})(),
|
|
120
|
+
dispose: () => cancel(id),
|
|
121
|
+
cancel: () => cancel(id)
|
|
122
|
+
};
|
|
123
|
+
} else throw new Error(`Pool task with id=${id} already exists!`);
|
|
124
|
+
}
|
|
125
|
+
const taskProgress = new Progress({
|
|
126
|
+
name: id,
|
|
127
|
+
totalUnits: config.max ?? 1,
|
|
128
|
+
completeUnits: config.resolved ?? 0
|
|
129
|
+
});
|
|
130
|
+
progress.addChild(taskProgress);
|
|
131
|
+
tasks[id] = {
|
|
132
|
+
id,
|
|
133
|
+
task,
|
|
134
|
+
priority: ++priority,
|
|
135
|
+
group: config.group,
|
|
136
|
+
state: "waiting",
|
|
137
|
+
max: config.max ?? 1,
|
|
138
|
+
resolved: config.resolved ?? 0,
|
|
139
|
+
done,
|
|
140
|
+
payload: config.payload,
|
|
141
|
+
progress: taskProgress,
|
|
142
|
+
setMax(units) {
|
|
143
|
+
taskProgress.setTotalUnits(units);
|
|
144
|
+
tasks[id].max = units;
|
|
145
|
+
didUpdate();
|
|
146
|
+
},
|
|
147
|
+
setResolved(units) {
|
|
148
|
+
taskProgress.setCompletetedUnits(units);
|
|
149
|
+
tasks[id].resolved = units;
|
|
150
|
+
didUpdate();
|
|
151
|
+
},
|
|
152
|
+
incResolved(inc = 1) {
|
|
153
|
+
taskProgress.incCompletedUnits(inc);
|
|
154
|
+
tasks[id].resolved += inc;
|
|
155
|
+
didUpdate();
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
++countMax;
|
|
159
|
+
performNext();
|
|
160
|
+
return {
|
|
161
|
+
id,
|
|
162
|
+
promise,
|
|
163
|
+
dispose: () => cancel(id),
|
|
164
|
+
cancel: () => cancel(id)
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
events,
|
|
169
|
+
cancel,
|
|
170
|
+
cancelAll,
|
|
171
|
+
hasById,
|
|
172
|
+
progress,
|
|
173
|
+
enqueue,
|
|
174
|
+
dispose,
|
|
175
|
+
waitFinishAll
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
//#endregion
|
|
180
|
+
export { usePool };
|
|
2
181
|
//# sourceMappingURL=pool.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pool.mjs","names":[],"sources":["../../../src/common/exec/pool.ts"],"sourcesContent":["import { useDispose } from '../dispose-defer'\nimport { Emitter } from '../msg/emitter'\nimport { uname, uuid } from '../uuid'\nimport { Progress } from './progress'\nimport { createPromise } from './promise'\n\nexport type PoolTaskIdConflictResolution = 'replace' | 'memoize' | 'prioritize' | 'error'\n\n// export enum PoolTaskIdConflictResolution {\n// /**\n// * Tasks with same `id` are replaced. Newest wins.\n// */\n// replace = 0,\n\n// /**\n// * Task with same `id` will continue to run. Reference is returned with option to cancel.\n// * Named \"memoize\" because the result of the task should always be the same for the same `id`,\n// * like e.g. a download.\n// */\n// memoize = 1,\n\n// /** Like memoize, but try to put on top of the list */\n// prioritize = 2,\n\n// /**\n// * Tasks with same `id` throw error\n// */\n// error = 3,\n\n// }\n\nexport interface PoolConfig {\n name?: string\n maxParallel?: number\n idConflictResolution?: PoolTaskIdConflictResolution\n}\n\nexport type PoolTaskFn<T = any> = (taskInfo: PoolTask<T>) => Promise<T>\n\nexport type PoolTaskState = 'waiting' | 'running' | 'finished'\n\n/** Task */\nexport interface PoolTask<T> {\n readonly id: string\n readonly task: PoolTaskFn<T>\n readonly done: (result?: any) => void\n readonly setMax: (max: number) => void\n readonly setResolved: (resolved: number) => void\n readonly incResolved: (inc?: number) => void\n state: PoolTaskState\n priority: number\n /** Same groups are executed only one at a time */\n group?: string\n\n progress: Progress\n max: number\n resolved: number\n\n result?: T\n payload?: unknown\n}\n\nexport interface PoolTaskEvents {\n didUpdate: (\n max: number,\n resolved: number,\n presentMax: number,\n presentResolved: number,\n ) => void\n didStart: (id: string) => void\n didCancel: (id: string) => void\n didFinish: () => void\n didResolve: (id: string, value: any) => void\n didReject: (id: string, error: any) => void\n}\n\n// todo: barrier\n// todo: dependents\n\nexport function usePool<T = any>(config: PoolConfig = {}) {\n const {\n maxParallel = 3,\n name = uname('pool'),\n idConflictResolution = 'memoize',\n } = config\n\n const events = new Emitter<PoolTaskEvents>()\n\n const dispose = useDispose()\n dispose.add(cancelAll)\n\n const progress = new Progress({ name })\n\n progress.on('progressCancelled', cancelAll)\n\n let countMax = 0\n let countResolved = 0\n let currentParallel = 0\n let priority = 0\n const tasks: Record<string, PoolTask<T>> = {}\n\n // const [allFinishedPromise, allFinishedResolve] = createPromise()\n\n async function waitFinishAll() {\n if (countMax > 0) {\n const [promise, resolve] = createPromise()\n events.once('didFinish', resolve)\n return promise\n }\n }\n\n async function cleanupFinished() {\n for (const id of Object.keys(tasks)) {\n const task = tasks[id]\n if (task.state === 'finished') {\n await tasks[id].progress.dispose()\n delete tasks[id]\n }\n }\n }\n\n function didFinish() {\n void events.emit('didFinish')\n // allFinishedResolve(countMax)\n countMax = 0\n countResolved = 0\n void cleanupFinished()\n progress.reset()\n }\n\n function didUpdate() {\n let presentMax = 0\n let presentResolved = 0\n for (const { max, resolved, state } of Object.values(tasks)) {\n presentMax += max\n presentResolved += state === 'finished' ? max : Math.min(max, resolved)\n }\n void events.emit(\n 'didUpdate',\n countMax,\n countResolved,\n presentMax,\n presentResolved,\n )\n }\n\n function performNext() {\n didUpdate()\n if (countMax > 0 && countMax === countResolved)\n didFinish()\n if (currentParallel >= maxParallel)\n return\n const waitingTasks = Object.values(tasks).filter(\n t => t.state === 'waiting',\n )\n if (waitingTasks.length > 0) {\n let taskInfo: PoolTask<T> | undefined\n for (const t of waitingTasks) {\n // Skip task if one of same group is running.\n // Forces serialized execution for subgroup of tasks.\n if (\n t.group != null\n && Object.values(tasks).some(\n tt =>\n tt.state === 'running'\n && tt.id !== t.id\n && tt.group === t.group,\n )\n ) {\n continue\n }\n\n // fifo\n if (taskInfo == null || t.priority < taskInfo.priority)\n taskInfo = t\n }\n if (taskInfo != null) {\n const id = taskInfo.id\n const done = taskInfo.done\n taskInfo.state = 'running'\n ++currentParallel\n void events.emit('didStart', id)\n\n const taskFinished = (result?: T) => {\n if (taskInfo) {\n taskInfo.result = result\n taskInfo.state = 'finished'\n taskInfo.resolved = taskInfo.max\n taskInfo.progress?.setCompleted()\n // void taskInfo.progress.dispose()\n }\n --currentParallel\n ++countResolved\n performNext()\n }\n\n taskInfo\n .task(taskInfo)\n .then((r) => {\n done(r)\n void events.emit('didResolve', id, r)\n taskFinished(r)\n })\n .catch((err) => {\n done()\n void events.emit('didReject', id, err)\n taskFinished()\n })\n }\n }\n }\n\n function cancel(id: string) {\n const taskInfo = tasks[id]\n if (taskInfo && taskInfo.state === 'waiting') {\n tasks[id].state = 'finished'\n ++countResolved\n void events.emit('didCancel', id)\n void tasks[id].progress.dispose()\n didUpdate()\n }\n }\n\n function cancelAll() {\n Object.keys(tasks).forEach(cancel)\n // progress.dispose()\n }\n\n function hasById(id: string) {\n return tasks[id] != null\n }\n\n function enqueue<P>(\n task: PoolTaskFn<T>,\n config: {\n id?: string\n max?: number\n resolved?: number\n group?: string\n idConflictResolution?: PoolTaskIdConflictResolution\n payload?: P\n } = {},\n ) {\n let done: any\n const promise: Promise<any> = new Promise(resolve => (done = resolve))\n const id = config.id ?? uuid()\n\n if (tasks[id] != null) {\n const resolution = config.idConflictResolution ?? idConflictResolution\n\n if (resolution === 'replace') {\n cancel(id)\n }\n else if (resolution === 'memoize' || resolution === 'prioritize') {\n const runningTask = tasks[id]\n\n if (resolution === 'prioritize')\n runningTask.priority = ++priority\n\n return {\n id,\n promise: (async () => {\n if (runningTask.state === 'finished')\n return tasks[id].result\n\n // todo: wait for task to finish\n })(),\n dispose: () => cancel(id),\n cancel: () => cancel(id),\n }\n }\n else {\n throw new Error(`Pool task with id=${id} already exists!`)\n }\n }\n\n const taskProgress = new Progress({\n name: id,\n totalUnits: config.max ?? 1,\n completeUnits: config.resolved ?? 0,\n })\n\n progress.addChild(taskProgress)\n\n tasks[id] = {\n id,\n task,\n priority: ++priority,\n group: config.group,\n state: 'waiting',\n max: config.max ?? 1,\n resolved: config.resolved ?? 0,\n done,\n payload: config.payload,\n progress: taskProgress,\n\n /** @deprecated should use `.progress` */\n setMax(units) {\n taskProgress.setTotalUnits(units)\n tasks[id].max = units\n didUpdate()\n },\n\n /** @deprecated should use `.progress` */\n setResolved(units) {\n taskProgress.setCompletetedUnits(units)\n tasks[id].resolved = units\n didUpdate()\n },\n\n /** @deprecated should use `.progress` */\n incResolved(inc = 1) {\n taskProgress.incCompletedUnits(inc)\n tasks[id].resolved += inc\n didUpdate()\n },\n }\n ++countMax\n performNext()\n\n return {\n id,\n promise,\n dispose: () => cancel(id),\n cancel: () => cancel(id),\n }\n }\n\n return {\n events,\n cancel,\n cancelAll,\n hasById,\n progress,\n enqueue,\n dispose,\n waitFinishAll,\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pool.mjs","names":[],"sources":["../../../src/common/exec/pool.ts"],"sourcesContent":["import { useDispose } from '../dispose-defer'\nimport { Emitter } from '../msg/emitter'\nimport { uname, uuid } from '../uuid'\nimport { Progress } from './progress'\nimport { createPromise } from './promise'\n\nexport type PoolTaskIdConflictResolution = 'replace' | 'memoize' | 'prioritize' | 'error'\n\n// export enum PoolTaskIdConflictResolution {\n// /**\n// * Tasks with same `id` are replaced. Newest wins.\n// */\n// replace = 0,\n\n// /**\n// * Task with same `id` will continue to run. Reference is returned with option to cancel.\n// * Named \"memoize\" because the result of the task should always be the same for the same `id`,\n// * like e.g. a download.\n// */\n// memoize = 1,\n\n// /** Like memoize, but try to put on top of the list */\n// prioritize = 2,\n\n// /**\n// * Tasks with same `id` throw error\n// */\n// error = 3,\n\n// }\n\nexport interface PoolConfig {\n name?: string\n maxParallel?: number\n idConflictResolution?: PoolTaskIdConflictResolution\n}\n\nexport type PoolTaskFn<T = any> = (taskInfo: PoolTask<T>) => Promise<T>\n\nexport type PoolTaskState = 'waiting' | 'running' | 'finished'\n\n/** Task */\nexport interface PoolTask<T> {\n readonly id: string\n readonly task: PoolTaskFn<T>\n readonly done: (result?: any) => void\n readonly setMax: (max: number) => void\n readonly setResolved: (resolved: number) => void\n readonly incResolved: (inc?: number) => void\n state: PoolTaskState\n priority: number\n /** Same groups are executed only one at a time */\n group?: string\n\n progress: Progress\n max: number\n resolved: number\n\n result?: T\n payload?: unknown\n}\n\nexport interface PoolTaskEvents {\n didUpdate: (\n max: number,\n resolved: number,\n presentMax: number,\n presentResolved: number,\n ) => void\n didStart: (id: string) => void\n didCancel: (id: string) => void\n didFinish: () => void\n didResolve: (id: string, value: any) => void\n didReject: (id: string, error: any) => void\n}\n\n// todo: barrier\n// todo: dependents\n\nexport function usePool<T = any>(config: PoolConfig = {}) {\n const {\n maxParallel = 3,\n name = uname('pool'),\n idConflictResolution = 'memoize',\n } = config\n\n const events = new Emitter<PoolTaskEvents>()\n\n const dispose = useDispose()\n dispose.add(cancelAll)\n\n const progress = new Progress({ name })\n\n progress.on('progressCancelled', cancelAll)\n\n let countMax = 0\n let countResolved = 0\n let currentParallel = 0\n let priority = 0\n const tasks: Record<string, PoolTask<T>> = {}\n\n // const [allFinishedPromise, allFinishedResolve] = createPromise()\n\n async function waitFinishAll() {\n if (countMax > 0) {\n const [promise, resolve] = createPromise()\n events.once('didFinish', resolve)\n return promise\n }\n }\n\n async function cleanupFinished() {\n for (const id of Object.keys(tasks)) {\n const task = tasks[id]\n if (task.state === 'finished') {\n await tasks[id].progress.dispose()\n delete tasks[id]\n }\n }\n }\n\n function didFinish() {\n void events.emit('didFinish')\n // allFinishedResolve(countMax)\n countMax = 0\n countResolved = 0\n void cleanupFinished()\n progress.reset()\n }\n\n function didUpdate() {\n let presentMax = 0\n let presentResolved = 0\n for (const { max, resolved, state } of Object.values(tasks)) {\n presentMax += max\n presentResolved += state === 'finished' ? max : Math.min(max, resolved)\n }\n void events.emit(\n 'didUpdate',\n countMax,\n countResolved,\n presentMax,\n presentResolved,\n )\n }\n\n function performNext() {\n didUpdate()\n if (countMax > 0 && countMax === countResolved)\n didFinish()\n if (currentParallel >= maxParallel)\n return\n const waitingTasks = Object.values(tasks).filter(\n t => t.state === 'waiting',\n )\n if (waitingTasks.length > 0) {\n let taskInfo: PoolTask<T> | undefined\n for (const t of waitingTasks) {\n // Skip task if one of same group is running.\n // Forces serialized execution for subgroup of tasks.\n if (\n t.group != null\n && Object.values(tasks).some(\n tt =>\n tt.state === 'running'\n && tt.id !== t.id\n && tt.group === t.group,\n )\n ) {\n continue\n }\n\n // fifo\n if (taskInfo == null || t.priority < taskInfo.priority)\n taskInfo = t\n }\n if (taskInfo != null) {\n const id = taskInfo.id\n const done = taskInfo.done\n taskInfo.state = 'running'\n ++currentParallel\n void events.emit('didStart', id)\n\n const taskFinished = (result?: T) => {\n if (taskInfo) {\n taskInfo.result = result\n taskInfo.state = 'finished'\n taskInfo.resolved = taskInfo.max\n taskInfo.progress?.setCompleted()\n // void taskInfo.progress.dispose()\n }\n --currentParallel\n ++countResolved\n performNext()\n }\n\n taskInfo\n .task(taskInfo)\n .then((r) => {\n done(r)\n void events.emit('didResolve', id, r)\n taskFinished(r)\n })\n .catch((err) => {\n done()\n void events.emit('didReject', id, err)\n taskFinished()\n })\n }\n }\n }\n\n function cancel(id: string) {\n const taskInfo = tasks[id]\n if (taskInfo && taskInfo.state === 'waiting') {\n tasks[id].state = 'finished'\n ++countResolved\n void events.emit('didCancel', id)\n void tasks[id].progress.dispose()\n didUpdate()\n }\n }\n\n function cancelAll() {\n Object.keys(tasks).forEach(cancel)\n // progress.dispose()\n }\n\n function hasById(id: string) {\n return tasks[id] != null\n }\n\n function enqueue<P>(\n task: PoolTaskFn<T>,\n config: {\n id?: string\n max?: number\n resolved?: number\n group?: string\n idConflictResolution?: PoolTaskIdConflictResolution\n payload?: P\n } = {},\n ) {\n let done: any\n const promise: Promise<any> = new Promise(resolve => (done = resolve))\n const id = config.id ?? uuid()\n\n if (tasks[id] != null) {\n const resolution = config.idConflictResolution ?? idConflictResolution\n\n if (resolution === 'replace') {\n cancel(id)\n }\n else if (resolution === 'memoize' || resolution === 'prioritize') {\n const runningTask = tasks[id]\n\n if (resolution === 'prioritize')\n runningTask.priority = ++priority\n\n return {\n id,\n promise: (async () => {\n if (runningTask.state === 'finished')\n return tasks[id].result\n\n // todo: wait for task to finish\n })(),\n dispose: () => cancel(id),\n cancel: () => cancel(id),\n }\n }\n else {\n throw new Error(`Pool task with id=${id} already exists!`)\n }\n }\n\n const taskProgress = new Progress({\n name: id,\n totalUnits: config.max ?? 1,\n completeUnits: config.resolved ?? 0,\n })\n\n progress.addChild(taskProgress)\n\n tasks[id] = {\n id,\n task,\n priority: ++priority,\n group: config.group,\n state: 'waiting',\n max: config.max ?? 1,\n resolved: config.resolved ?? 0,\n done,\n payload: config.payload,\n progress: taskProgress,\n\n /** @deprecated should use `.progress` */\n setMax(units) {\n taskProgress.setTotalUnits(units)\n tasks[id].max = units\n didUpdate()\n },\n\n /** @deprecated should use `.progress` */\n setResolved(units) {\n taskProgress.setCompletetedUnits(units)\n tasks[id].resolved = units\n didUpdate()\n },\n\n /** @deprecated should use `.progress` */\n incResolved(inc = 1) {\n taskProgress.incCompletedUnits(inc)\n tasks[id].resolved += inc\n didUpdate()\n },\n }\n ++countMax\n performNext()\n\n return {\n id,\n promise,\n dispose: () => cancel(id),\n cancel: () => cancel(id),\n }\n }\n\n return {\n events,\n cancel,\n cancelAll,\n hasById,\n progress,\n enqueue,\n dispose,\n waitFinishAll,\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,150 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_common_data_array = require('../data/array.cjs');
|
|
3
|
+
const require_common_dispose_defer = require('../dispose-defer.cjs');
|
|
4
|
+
const require_common_msg_emitter = require('../msg/emitter.cjs');
|
|
5
|
+
const require_common_uuid = require('../uuid.cjs');
|
|
6
|
+
|
|
7
|
+
//#region src/common/exec/progress.ts
|
|
8
|
+
/**
|
|
9
|
+
* Progress helper with these properties:
|
|
10
|
+
*
|
|
11
|
+
* - `totalUnits` and `completedUnits` for progress
|
|
12
|
+
* - Can be cancelled
|
|
13
|
+
* - Sends events on cancel, changed and dispose
|
|
14
|
+
* - Supports children and propagates values.
|
|
15
|
+
* Total progress is sum of all units in the tree.
|
|
16
|
+
* - On `dispose` child removes itself from parent.
|
|
17
|
+
*/
|
|
18
|
+
var Progress = class Progress extends require_common_msg_emitter.Emitter {
|
|
19
|
+
_totalUnits;
|
|
20
|
+
_completedUnits;
|
|
21
|
+
_isCancelled = false;
|
|
22
|
+
_resetWhenFinished = true;
|
|
23
|
+
_children = [];
|
|
24
|
+
dispose = require_common_dispose_defer.useDispose();
|
|
25
|
+
name;
|
|
26
|
+
constructor(opt = {}) {
|
|
27
|
+
super();
|
|
28
|
+
this._totalUnits = opt.totalUnits ?? 0;
|
|
29
|
+
this._completedUnits = opt.completeUnits ?? 0;
|
|
30
|
+
this._resetWhenFinished = opt.resetWhenFinished ?? true;
|
|
31
|
+
this.name = opt.name ?? require_common_uuid.uname("progress");
|
|
32
|
+
this.dispose.add(async () => {
|
|
33
|
+
for (const child of this._children) await child.dispose();
|
|
34
|
+
await this.emit("progressDispose", this);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Notify others about changes and reset on completion, if flag is set. */
|
|
38
|
+
update() {
|
|
39
|
+
this.emit("progressChanged", this);
|
|
40
|
+
if (this._isCancelled && this._resetWhenFinished) {
|
|
41
|
+
if (this.getTotalUnits() <= this.getCompletedUnits()) this.reset();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Fresh start */
|
|
45
|
+
reset() {
|
|
46
|
+
if (this._isCancelled) {
|
|
47
|
+
this._isCancelled = false;
|
|
48
|
+
for (const child of this._children) child.reset();
|
|
49
|
+
this.update();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Notify and mark as cancelled. May take some time before having an effect. */
|
|
53
|
+
async cancel() {
|
|
54
|
+
if (!this._isCancelled) {
|
|
55
|
+
this._isCancelled = true;
|
|
56
|
+
await this.emit("progressCancelled", this);
|
|
57
|
+
for (const child of this._children) await child.cancel();
|
|
58
|
+
this.update();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Add child progress, which count into its parents units. On `dispose` it will auto remove itself from parent. */
|
|
62
|
+
addChild(child) {
|
|
63
|
+
child.on("progressDispose", () => this.removeChild(child));
|
|
64
|
+
child.on("progressChanged", () => this.update());
|
|
65
|
+
if (!this._children.includes(child)) this._children.push(child);
|
|
66
|
+
this.update();
|
|
67
|
+
}
|
|
68
|
+
/** Create child progress. */
|
|
69
|
+
createChildProgress(opt) {
|
|
70
|
+
const progress = new Progress(opt);
|
|
71
|
+
this.addChild(progress);
|
|
72
|
+
return progress;
|
|
73
|
+
}
|
|
74
|
+
removeChild(child) {
|
|
75
|
+
require_common_data_array.arrayRemoveElement(this._children, child);
|
|
76
|
+
this.update();
|
|
77
|
+
}
|
|
78
|
+
/** Total units including children */
|
|
79
|
+
getTotalUnits() {
|
|
80
|
+
if (this.isIndeterminate()) return 0;
|
|
81
|
+
let units = this._totalUnits;
|
|
82
|
+
for (const child of this._children) units += child.getTotalUnits();
|
|
83
|
+
return units;
|
|
84
|
+
}
|
|
85
|
+
/** Completed units including children */
|
|
86
|
+
getCompletedUnits() {
|
|
87
|
+
if (this.isIndeterminate()) return 0;
|
|
88
|
+
let units = this._completedUnits;
|
|
89
|
+
for (const child of this._children) units += child.getCompletedUnits();
|
|
90
|
+
return units;
|
|
91
|
+
}
|
|
92
|
+
/** Cannot calculate progress, because totalUnits are missing. Special representation in UI. */
|
|
93
|
+
isIndeterminate() {
|
|
94
|
+
return this._totalUnits <= 0 && this._children.length <= 0;
|
|
95
|
+
}
|
|
96
|
+
isCancelled() {
|
|
97
|
+
return this._isCancelled;
|
|
98
|
+
}
|
|
99
|
+
/** Either disposed or all units completed. */
|
|
100
|
+
isFinished() {
|
|
101
|
+
return this.dispose.isDisposed() || !this.isIndeterminate() && this.getTotalUnits() <= this.getCompletedUnits();
|
|
102
|
+
}
|
|
103
|
+
/** Value from 0 to 1, where 1 is 100% completeness. */
|
|
104
|
+
getFraction() {
|
|
105
|
+
if (this.isIndeterminate()) return 0;
|
|
106
|
+
let value = this.getCompletedUnits() / this.getTotalUnits();
|
|
107
|
+
if (Number.isNaN(value)) value = 0;
|
|
108
|
+
return Math.min(1, Math.max(0, value));
|
|
109
|
+
}
|
|
110
|
+
getChildrenCount() {
|
|
111
|
+
return this._children.length;
|
|
112
|
+
}
|
|
113
|
+
/** Change total units. */
|
|
114
|
+
setTotalUnits(units, completedUnits) {
|
|
115
|
+
this._totalUnits = units;
|
|
116
|
+
if (completedUnits != null) this._completedUnits = completedUnits;
|
|
117
|
+
this.update();
|
|
118
|
+
}
|
|
119
|
+
/** Relatively change total units. */
|
|
120
|
+
incTotalUnits(step = 1) {
|
|
121
|
+
this._totalUnits += step;
|
|
122
|
+
this.update();
|
|
123
|
+
}
|
|
124
|
+
/** Set fixed number of completed units. */
|
|
125
|
+
setCompletetedUnits(units) {
|
|
126
|
+
this._completedUnits = units;
|
|
127
|
+
this.update();
|
|
128
|
+
}
|
|
129
|
+
/** Set to 100% without disposing. */
|
|
130
|
+
setCompleted() {
|
|
131
|
+
this._completedUnits = this._totalUnits;
|
|
132
|
+
this.update();
|
|
133
|
+
}
|
|
134
|
+
/** Dynamically change completed units. */
|
|
135
|
+
incCompletedUnits(step = 1) {
|
|
136
|
+
this._completedUnits += step;
|
|
137
|
+
this.update();
|
|
138
|
+
}
|
|
139
|
+
/** Progress tree to string for debuggin purposes. Consider using `name` attribute of Progress. */
|
|
140
|
+
toString(indent = 0) {
|
|
141
|
+
let s = `${" ".repeat(indent)}${this.name}: ${this._completedUnits} of ${this._totalUnits} units, ${Math.floor(this.getFraction() * 100)} %, cancel=${this._isCancelled}\n`;
|
|
142
|
+
for (const child of this._children) s += child.toString(indent + 1);
|
|
143
|
+
if (indent === 0) return s.trim();
|
|
144
|
+
return s;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
//#endregion
|
|
149
|
+
exports.Progress = Progress;
|
|
2
150
|
//# sourceMappingURL=progress.cjs.map
|