@dbx-tools/shared-core 0.3.44 → 0.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/lib/index.d.ts +36 -0
- package/lib/index.js +30 -0
- package/lib/src/async.d.ts +152 -0
- package/lib/src/async.js +163 -0
- package/lib/src/brand.d.ts +94 -0
- package/lib/src/brand.js +123 -0
- package/lib/src/error.d.ts +76 -0
- package/lib/src/error.js +168 -0
- package/lib/src/function.d.ts +38 -0
- package/lib/src/function.js +44 -0
- package/lib/src/hash.d.ts +102 -0
- package/lib/src/hash.js +274 -0
- package/lib/src/http.d.ts +79 -0
- package/lib/src/http.js +189 -0
- package/lib/src/json.d.ts +48 -0
- package/lib/src/json.js +49 -0
- package/lib/src/log.d.ts +86 -0
- package/lib/src/log.js +352 -0
- package/lib/src/net.d.ts +246 -0
- package/lib/src/net.js +465 -0
- package/lib/src/object.d.ts +382 -0
- package/lib/src/object.js +749 -0
- package/lib/src/predicate.d.ts +81 -0
- package/lib/src/predicate.js +43 -0
- package/lib/src/string.d.ts +221 -0
- package/lib/src/string.js +509 -0
- package/lib/src/token.d.ts +30 -0
- package/lib/src/token.js +126 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +9 -5
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export * as async from "./src/async.js";
|
|
2
|
+
export * as brand from "./src/brand.js";
|
|
3
|
+
export * as error from "./src/error.js";
|
|
4
|
+
export * as functionModule from "./src/function.js";
|
|
5
|
+
export * as hash from "./src/hash.js";
|
|
6
|
+
export * as http from "./src/http.js";
|
|
7
|
+
export * as json from "./src/json.js";
|
|
8
|
+
export * as log from "./src/log.js";
|
|
9
|
+
export * as net from "./src/net.js";
|
|
10
|
+
export * as object from "./src/object.js";
|
|
11
|
+
export * as predicate from "./src/predicate.js";
|
|
12
|
+
export * as string from "./src/string.js";
|
|
13
|
+
export * as token from "./src/token.js";
|
|
14
|
+
export { poll, tieAbortSignal, combineAbortSignals, sleep } from "./src/async.js";
|
|
15
|
+
export type { PollContext, PollProducer, PollOptions } from "./src/async.js";
|
|
16
|
+
export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, parseBrandContext, defaultBrandContext, brandContextJsonSchema, brandContextPrompt } from "./src/brand.js";
|
|
17
|
+
export type { BrandContext, BrandContextInput, BrandAssetSet } from "./src/brand.js";
|
|
18
|
+
export { toError, errorMessage, errorMessages, errorNodes, errorContext } from "./src/error.js";
|
|
19
|
+
export type { ErrorContext } from "./src/error.js";
|
|
20
|
+
export { memoize } from "./src/function.js";
|
|
21
|
+
export type { MemoizeOptions } from "./src/function.js";
|
|
22
|
+
export { id, fnvHash, fnvHashWithOptions, toBase32 } from "./src/hash.js";
|
|
23
|
+
export { forEachHeaderValue, parseCookies, createFetchError } from "./src/http.js";
|
|
24
|
+
export type { HeaderLike } from "./src/http.js";
|
|
25
|
+
export { parse, parseRecord } from "./src/json.js";
|
|
26
|
+
export { isLevelEnabled, logger } from "./src/log.js";
|
|
27
|
+
export type { LogLevel, Logger } from "./src/log.js";
|
|
28
|
+
export { urlBuilder, pathMatch, parseEmails, isEmail, parseIp, parseCidr, ipInCidr, findContainingCidr, isLoopbackHost } from "./src/net.js";
|
|
29
|
+
export type { UrlLike, IpVersion, ParsedIp, Cidr, UrlBuilder, ParseEmailsOptions } from "./src/net.js";
|
|
30
|
+
export { isOneOrMany, isCollection, isEmpty, values, isContainer, map, filter, nonNull, flatMap, flat, distinct, concat, take, group, find, findLast, findIndex, findLastIndex, some, every, forEach, at, toOneOrMany, toArray, sequence, generator, isRecord, toBoolean, deepEqual } from "./src/object.js";
|
|
31
|
+
export type { Sequence, Container, Collection, OneOrMany, NameLike, NonFunctionKeys, DeepEqualComparator } from "./src/object.js";
|
|
32
|
+
export { create } from "./src/predicate.js";
|
|
33
|
+
export type { PredicateFunction, TypePredicateFunction, PredicateInput, Predicate } from "./src/predicate.js";
|
|
34
|
+
export { tokenizeWithOptions, tokenize, toIdentifierWithOptions, toIdentifier, toSlugWithOptions, toSlug, trimToNull, parseList, trimToEmpty, firstNonEmpty, escapeHtml, toUniqueSlug, toDescription, pluralize, toLabel, capitalize } from "./src/string.js";
|
|
35
|
+
export type { TokenizeOptions, KeyOptions, IdentifierOptions, Description } from "./src/string.js";
|
|
36
|
+
export { getAccessTokenPayload, getAccessTokenScopes, includesAccessTokenScope } from "./src/token.js";
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// GENERATED by projen watch - DO NOT EDIT.
|
|
2
|
+
// Regenerated from the exporting modules in ./src.
|
|
3
|
+
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
|
+
export * as async from "./src/async.js";
|
|
5
|
+
export * as brand from "./src/brand.js";
|
|
6
|
+
export * as error from "./src/error.js";
|
|
7
|
+
export * as functionModule from "./src/function.js";
|
|
8
|
+
export * as hash from "./src/hash.js";
|
|
9
|
+
export * as http from "./src/http.js";
|
|
10
|
+
export * as json from "./src/json.js";
|
|
11
|
+
export * as log from "./src/log.js";
|
|
12
|
+
export * as net from "./src/net.js";
|
|
13
|
+
export * as object from "./src/object.js";
|
|
14
|
+
export * as predicate from "./src/predicate.js";
|
|
15
|
+
export * as string from "./src/string.js";
|
|
16
|
+
export * as token from "./src/token.js";
|
|
17
|
+
export { poll, tieAbortSignal, combineAbortSignals, sleep } from "./src/async.js";
|
|
18
|
+
export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, parseBrandContext, defaultBrandContext, brandContextJsonSchema, brandContextPrompt } from "./src/brand.js";
|
|
19
|
+
export { toError, errorMessage, errorMessages, errorNodes, errorContext } from "./src/error.js";
|
|
20
|
+
export { memoize } from "./src/function.js";
|
|
21
|
+
export { id, fnvHash, fnvHashWithOptions, toBase32 } from "./src/hash.js";
|
|
22
|
+
export { forEachHeaderValue, parseCookies, createFetchError } from "./src/http.js";
|
|
23
|
+
export { parse, parseRecord } from "./src/json.js";
|
|
24
|
+
export { isLevelEnabled, logger } from "./src/log.js";
|
|
25
|
+
export { urlBuilder, pathMatch, parseEmails, isEmail, parseIp, parseCidr, ipInCidr, findContainingCidr, isLoopbackHost } from "./src/net.js";
|
|
26
|
+
export { isOneOrMany, isCollection, isEmpty, values, isContainer, map, filter, nonNull, flatMap, flat, distinct, concat, take, group, find, findLast, findIndex, findLastIndex, some, every, forEach, at, toOneOrMany, toArray, sequence, generator, isRecord, toBoolean, deepEqual } from "./src/object.js";
|
|
27
|
+
export { create } from "./src/predicate.js";
|
|
28
|
+
export { tokenizeWithOptions, tokenize, toIdentifierWithOptions, toIdentifier, toSlugWithOptions, toSlug, trimToNull, parseList, trimToEmpty, firstNonEmpty, escapeHtml, toUniqueSlug, toDescription, pluralize, toLabel, capitalize } from "./src/string.js";
|
|
29
|
+
export { getAccessTokenPayload, getAccessTokenScopes, includesAccessTokenScope } from "./src/token.js";
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssS0FBSyxNQUFNLGFBQWEsQ0FBQztBQUNyQyxPQUFPLEtBQUssS0FBSyxNQUFNLGFBQWEsQ0FBQztBQUNyQyxPQUFPLEtBQUssS0FBSyxNQUFNLGFBQWEsQ0FBQztBQUNyQyxPQUFPLEtBQUssY0FBYyxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxHQUFHLE1BQU0sV0FBVyxDQUFDO0FBQ2pDLE9BQU8sS0FBSyxHQUFHLE1BQU0sV0FBVyxDQUFDO0FBQ2pDLE9BQU8sS0FBSyxNQUFNLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxTQUFTLE1BQU0saUJBQWlCLENBQUM7QUFDN0MsT0FBTyxLQUFLLE1BQU0sTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxLQUFLLEtBQUssTUFBTSxhQUFhLENBQUM7QUFDckMsT0FBTyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRS9FLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxtQkFBbUIsRUFBRSxzQkFBc0IsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVyTixPQUFPLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUU3RixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekMsT0FBTyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsUUFBUSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFaEYsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDaEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFbkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFMUksT0FBTyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFMVMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXpDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxRQUFRLEVBQUUsdUJBQXVCLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFM1AsT0FBTyxFQUFFLHFCQUFxQixFQUFFLG9CQUFvQixFQUFFLHdCQUF3QixFQUFFLE1BQU0sYUFBYSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gR0VORVJBVEVEIGJ5IHByb2plbiB3YXRjaCAtIERPIE5PVCBFRElULlxuLy8gUmVnZW5lcmF0ZWQgZnJvbSB0aGUgZXhwb3J0aW5nIG1vZHVsZXMgaW4gLi9zcmMuXG4vLyBIYW5kIGVkaXRzIGFyZSBvdmVyd3JpdHRlbiBvbiB0aGUgbmV4dCB3YXRjaDsgdGhpcyBmaWxlIGlzIHJlYWQtb25seS5cblxuZXhwb3J0ICogYXMgYXN5bmMgZnJvbSBcIi4vc3JjL2FzeW5jXCI7XG5leHBvcnQgKiBhcyBicmFuZCBmcm9tIFwiLi9zcmMvYnJhbmRcIjtcbmV4cG9ydCAqIGFzIGVycm9yIGZyb20gXCIuL3NyYy9lcnJvclwiO1xuZXhwb3J0ICogYXMgZnVuY3Rpb25Nb2R1bGUgZnJvbSBcIi4vc3JjL2Z1bmN0aW9uXCI7XG5leHBvcnQgKiBhcyBoYXNoIGZyb20gXCIuL3NyYy9oYXNoXCI7XG5leHBvcnQgKiBhcyBodHRwIGZyb20gXCIuL3NyYy9odHRwXCI7XG5leHBvcnQgKiBhcyBqc29uIGZyb20gXCIuL3NyYy9qc29uXCI7XG5leHBvcnQgKiBhcyBsb2cgZnJvbSBcIi4vc3JjL2xvZ1wiO1xuZXhwb3J0ICogYXMgbmV0IGZyb20gXCIuL3NyYy9uZXRcIjtcbmV4cG9ydCAqIGFzIG9iamVjdCBmcm9tIFwiLi9zcmMvb2JqZWN0XCI7XG5leHBvcnQgKiBhcyBwcmVkaWNhdGUgZnJvbSBcIi4vc3JjL3ByZWRpY2F0ZVwiO1xuZXhwb3J0ICogYXMgc3RyaW5nIGZyb20gXCIuL3NyYy9zdHJpbmdcIjtcbmV4cG9ydCAqIGFzIHRva2VuIGZyb20gXCIuL3NyYy90b2tlblwiO1xuZXhwb3J0IHsgcG9sbCwgdGllQWJvcnRTaWduYWwsIGNvbWJpbmVBYm9ydFNpZ25hbHMsIHNsZWVwIH0gZnJvbSBcIi4vc3JjL2FzeW5jXCI7XG5leHBvcnQgdHlwZSB7IFBvbGxDb250ZXh0LCBQb2xsUHJvZHVjZXIsIFBvbGxPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2FzeW5jXCI7XG5leHBvcnQgeyBERUZBVUxUX0JSQU5EX0FTU0VUUywgQnJhbmRBc3NldFNldFNjaGVtYSwgQnJhbmRDb2xvcnNTY2hlbWEsIEJyYW5kVm9pY2VTY2hlbWEsIEJyYW5kQ29udGV4dFNjaGVtYSwgcGFyc2VCcmFuZENvbnRleHQsIGRlZmF1bHRCcmFuZENvbnRleHQsIGJyYW5kQ29udGV4dEpzb25TY2hlbWEsIGJyYW5kQ29udGV4dFByb21wdCB9IGZyb20gXCIuL3NyYy9icmFuZFwiO1xuZXhwb3J0IHR5cGUgeyBCcmFuZENvbnRleHQsIEJyYW5kQ29udGV4dElucHV0LCBCcmFuZEFzc2V0U2V0IH0gZnJvbSBcIi4vc3JjL2JyYW5kXCI7XG5leHBvcnQgeyB0b0Vycm9yLCBlcnJvck1lc3NhZ2UsIGVycm9yTWVzc2FnZXMsIGVycm9yTm9kZXMsIGVycm9yQ29udGV4dCB9IGZyb20gXCIuL3NyYy9lcnJvclwiO1xuZXhwb3J0IHR5cGUgeyBFcnJvckNvbnRleHQgfSBmcm9tIFwiLi9zcmMvZXJyb3JcIjtcbmV4cG9ydCB7IG1lbW9pemUgfSBmcm9tIFwiLi9zcmMvZnVuY3Rpb25cIjtcbmV4cG9ydCB0eXBlIHsgTWVtb2l6ZU9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvZnVuY3Rpb25cIjtcbmV4cG9ydCB7IGlkLCBmbnZIYXNoLCBmbnZIYXNoV2l0aE9wdGlvbnMsIHRvQmFzZTMyIH0gZnJvbSBcIi4vc3JjL2hhc2hcIjtcbmV4cG9ydCB7IGZvckVhY2hIZWFkZXJWYWx1ZSwgcGFyc2VDb29raWVzLCBjcmVhdGVGZXRjaEVycm9yIH0gZnJvbSBcIi4vc3JjL2h0dHBcIjtcbmV4cG9ydCB0eXBlIHsgSGVhZGVyTGlrZSB9IGZyb20gXCIuL3NyYy9odHRwXCI7XG5leHBvcnQgeyBwYXJzZSwgcGFyc2VSZWNvcmQgfSBmcm9tIFwiLi9zcmMvanNvblwiO1xuZXhwb3J0IHsgaXNMZXZlbEVuYWJsZWQsIGxvZ2dlciB9IGZyb20gXCIuL3NyYy9sb2dcIjtcbmV4cG9ydCB0eXBlIHsgTG9nTGV2ZWwsIExvZ2dlciB9IGZyb20gXCIuL3NyYy9sb2dcIjtcbmV4cG9ydCB7IHVybEJ1aWxkZXIsIHBhdGhNYXRjaCwgcGFyc2VFbWFpbHMsIGlzRW1haWwsIHBhcnNlSXAsIHBhcnNlQ2lkciwgaXBJbkNpZHIsIGZpbmRDb250YWluaW5nQ2lkciwgaXNMb29wYmFja0hvc3QgfSBmcm9tIFwiLi9zcmMvbmV0XCI7XG5leHBvcnQgdHlwZSB7IFVybExpa2UsIElwVmVyc2lvbiwgUGFyc2VkSXAsIENpZHIsIFVybEJ1aWxkZXIsIFBhcnNlRW1haWxzT3B0aW9ucyB9IGZyb20gXCIuL3NyYy9uZXRcIjtcbmV4cG9ydCB7IGlzT25lT3JNYW55LCBpc0NvbGxlY3Rpb24sIGlzRW1wdHksIHZhbHVlcywgaXNDb250YWluZXIsIG1hcCwgZmlsdGVyLCBub25OdWxsLCBmbGF0TWFwLCBmbGF0LCBkaXN0aW5jdCwgY29uY2F0LCB0YWtlLCBncm91cCwgZmluZCwgZmluZExhc3QsIGZpbmRJbmRleCwgZmluZExhc3RJbmRleCwgc29tZSwgZXZlcnksIGZvckVhY2gsIGF0LCB0b09uZU9yTWFueSwgdG9BcnJheSwgc2VxdWVuY2UsIGdlbmVyYXRvciwgaXNSZWNvcmQsIHRvQm9vbGVhbiwgZGVlcEVxdWFsIH0gZnJvbSBcIi4vc3JjL29iamVjdFwiO1xuZXhwb3J0IHR5cGUgeyBTZXF1ZW5jZSwgQ29udGFpbmVyLCBDb2xsZWN0aW9uLCBPbmVPck1hbnksIE5hbWVMaWtlLCBOb25GdW5jdGlvbktleXMsIERlZXBFcXVhbENvbXBhcmF0b3IgfSBmcm9tIFwiLi9zcmMvb2JqZWN0XCI7XG5leHBvcnQgeyBjcmVhdGUgfSBmcm9tIFwiLi9zcmMvcHJlZGljYXRlXCI7XG5leHBvcnQgdHlwZSB7IFByZWRpY2F0ZUZ1bmN0aW9uLCBUeXBlUHJlZGljYXRlRnVuY3Rpb24sIFByZWRpY2F0ZUlucHV0LCBQcmVkaWNhdGUgfSBmcm9tIFwiLi9zcmMvcHJlZGljYXRlXCI7XG5leHBvcnQgeyB0b2tlbml6ZVdpdGhPcHRpb25zLCB0b2tlbml6ZSwgdG9JZGVudGlmaWVyV2l0aE9wdGlvbnMsIHRvSWRlbnRpZmllciwgdG9TbHVnV2l0aE9wdGlvbnMsIHRvU2x1ZywgdHJpbVRvTnVsbCwgcGFyc2VMaXN0LCB0cmltVG9FbXB0eSwgZmlyc3ROb25FbXB0eSwgZXNjYXBlSHRtbCwgdG9VbmlxdWVTbHVnLCB0b0Rlc2NyaXB0aW9uLCBwbHVyYWxpemUsIHRvTGFiZWwsIGNhcGl0YWxpemUgfSBmcm9tIFwiLi9zcmMvc3RyaW5nXCI7XG5leHBvcnQgdHlwZSB7IFRva2VuaXplT3B0aW9ucywgS2V5T3B0aW9ucywgSWRlbnRpZmllck9wdGlvbnMsIERlc2NyaXB0aW9uIH0gZnJvbSBcIi4vc3JjL3N0cmluZ1wiO1xuZXhwb3J0IHsgZ2V0QWNjZXNzVG9rZW5QYXlsb2FkLCBnZXRBY2Nlc3NUb2tlblNjb3BlcywgaW5jbHVkZXNBY2Nlc3NUb2tlblNjb3BlIH0gZnJvbSBcIi4vc3JjL3Rva2VuXCI7XG4iXX0=
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-iteration context handed to {@link PollProducer} and the
|
|
3
|
+
* predicate on each step of a {@link poll} loop. Bundles the
|
|
4
|
+
* iteration metadata so the call signatures stay stable as `poll`
|
|
5
|
+
* grows additional fields.
|
|
6
|
+
*
|
|
7
|
+
* `signal` is owned by `poll`: it tracks the external
|
|
8
|
+
* `PollOptions.signal` (when supplied) and also fires when the
|
|
9
|
+
* consumer breaks out of the loop, so producers can forward it to
|
|
10
|
+
* any in-flight work (`fetch`, SDK calls, etc.) and have a single
|
|
11
|
+
* cancellation source tear down both the request and the loop.
|
|
12
|
+
*
|
|
13
|
+
* `attributes` is a mutable scratchpad shared across every
|
|
14
|
+
* iteration of a single `poll` run. The same object reference is
|
|
15
|
+
* passed each call so writes from one iteration are visible to the
|
|
16
|
+
* next - useful for stashing per-loop state (retry counters, start
|
|
17
|
+
* timestamps, anything you'd otherwise close over via a let).
|
|
18
|
+
* Generic `A` lets callers type the bag; defaults to
|
|
19
|
+
* `Record<string, unknown>`.
|
|
20
|
+
*/
|
|
21
|
+
export interface PollContext<T, A = Record<string, unknown>> {
|
|
22
|
+
/** Zero-based iteration index (`0` on the first call). */
|
|
23
|
+
attempt: number;
|
|
24
|
+
/** Value yielded on the prior iteration; `undefined` on the first. */
|
|
25
|
+
previous: T | undefined;
|
|
26
|
+
/** Cancellation handle. Always defined; forward to in-flight work. */
|
|
27
|
+
signal: AbortSignal;
|
|
28
|
+
/** Per-run mutable scratchpad shared across iterations. */
|
|
29
|
+
attributes: A;
|
|
30
|
+
}
|
|
31
|
+
/** One step of a {@link poll} loop. See {@link PollContext}. */
|
|
32
|
+
export type PollProducer<T, A = Record<string, unknown>> = (ctx: PollContext<T, A>) => T | PromiseLike<T>;
|
|
33
|
+
export interface PollOptions<T, A = Record<string, unknown>> {
|
|
34
|
+
/** Milliseconds to wait between polls. */
|
|
35
|
+
intervalMs: number;
|
|
36
|
+
/**
|
|
37
|
+
* Predicate evaluated against each yielded value: return `true` to
|
|
38
|
+
* keep it, `false` to skip it (without stopping the loop). May be
|
|
39
|
+
* sync or async - a `PromiseLike<boolean>` is awaited before the
|
|
40
|
+
* decision is made. Receives the same {@link PollContext} as the
|
|
41
|
+
* producer (same `signal`, same `attributes` bag). The special
|
|
42
|
+
* value `"distinct"` skips a value that deep-equals the previous
|
|
43
|
+
* one.
|
|
44
|
+
*/
|
|
45
|
+
filter?: ((value: T, ctx: PollContext<T, A>) => boolean | PromiseLike<boolean>) | "distinct";
|
|
46
|
+
/**
|
|
47
|
+
* Predicate evaluated against each yielded value: return `true` to
|
|
48
|
+
* keep polling, `false` to stop. May be sync or async. Omit to poll
|
|
49
|
+
* forever (the consumer stops by breaking out of the loop or by
|
|
50
|
+
* aborting `signal`).
|
|
51
|
+
*/
|
|
52
|
+
predicate?: (value: T, ctx: PollContext<T, A>) => boolean | PromiseLike<boolean>;
|
|
53
|
+
/**
|
|
54
|
+
* External cancellation handle. Tied into the internal signal that
|
|
55
|
+
* `poll` hands to `producer`, so aborting it tears down both the
|
|
56
|
+
* in-flight request and the inter-poll sleep.
|
|
57
|
+
*/
|
|
58
|
+
signal?: AbortSignal;
|
|
59
|
+
/**
|
|
60
|
+
* Hard upper bound on the total lifetime of the poll loop, in
|
|
61
|
+
* milliseconds. When the budget elapses, `poll` aborts its internal
|
|
62
|
+
* signal so the in-flight producer and inter-poll sleep both tear
|
|
63
|
+
* down promptly, and the loop throws the `TimeoutError`
|
|
64
|
+
* `DOMException` produced by `AbortSignal.timeout(timeoutMs)`. The
|
|
65
|
+
* budget starts ticking the moment the generator is created.
|
|
66
|
+
*/
|
|
67
|
+
timeoutMs?: number;
|
|
68
|
+
/**
|
|
69
|
+
* Initial value for `ctx.attributes`. Defaults to `{}`. The same
|
|
70
|
+
* object is reused across iterations, so callers can pre-populate
|
|
71
|
+
* fields (timers, retry counters, etc.) and the producer /
|
|
72
|
+
* predicate can mutate them in place.
|
|
73
|
+
*/
|
|
74
|
+
attributes?: A;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Async iterable that drives a periodic poll. Each iteration:
|
|
78
|
+
*
|
|
79
|
+
* 1. Builds a {@link PollContext} (`attempt`, `previous`, `signal`,
|
|
80
|
+
* shared `attributes`) and calls `producer(ctx)`; yields the
|
|
81
|
+
* resolved value (subject to `filter`).
|
|
82
|
+
* 2. Evaluates `options.predicate(value, ctx)`; stops when it
|
|
83
|
+
* returns (or resolves to) `false`.
|
|
84
|
+
* 3. Sleeps `options.intervalMs` before the next attempt.
|
|
85
|
+
*
|
|
86
|
+
* The first call runs immediately (no leading sleep) so the consumer
|
|
87
|
+
* sees a value without waiting an interval. Errors thrown by
|
|
88
|
+
* `producer` propagate through the generator.
|
|
89
|
+
*
|
|
90
|
+
* `poll` always creates an internal `AbortController` and exposes
|
|
91
|
+
* `internal.signal` as `ctx.signal`, so producers can rely on a
|
|
92
|
+
* defined signal without a nullish check. The external
|
|
93
|
+
* `options.signal` is tied in, and a `try/finally` aborts the
|
|
94
|
+
* internal signal when the consumer breaks out of the `for await`
|
|
95
|
+
* (or the loop throws), so any producer work still holding the
|
|
96
|
+
* signal sees the cancellation too.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* for await (const msg of poll(
|
|
100
|
+
* async ({ signal }) =>
|
|
101
|
+
* client.genie.getMessage({ ... }, { abortSignal: signal }),
|
|
102
|
+
* {
|
|
103
|
+
* intervalMs: 250,
|
|
104
|
+
* predicate: (m) => !TERMINAL_STATUSES.has(m.status),
|
|
105
|
+
* signal: controller.signal,
|
|
106
|
+
* },
|
|
107
|
+
* )) {
|
|
108
|
+
* render(msg);
|
|
109
|
+
* }
|
|
110
|
+
*/
|
|
111
|
+
export declare function poll<T, A = Record<string, unknown>>(producer: PollProducer<T, A>, options: PollOptions<T, A>): AsyncGenerator<T, void, void>;
|
|
112
|
+
/**
|
|
113
|
+
* Tie a child `AbortController` to a parent signal. The child aborts
|
|
114
|
+
* whenever the parent aborts; aborting the child does not affect the
|
|
115
|
+
* parent (so a fetch-level cancel doesn't tear down the main poll loop).
|
|
116
|
+
*/
|
|
117
|
+
export declare function tieAbortSignal(child: AbortController, parent?: AbortSignal): void;
|
|
118
|
+
/**
|
|
119
|
+
* Combine several optional cancellation sources into one signal that aborts
|
|
120
|
+
* as soon as any of them does.
|
|
121
|
+
*
|
|
122
|
+
* The usual caller is an operation that has to honor more than one source at
|
|
123
|
+
* once - a caller's own signal (a closed connection, an agent run being
|
|
124
|
+
* cancelled) plus one derived from a timeout - where the awaited I/O accepts
|
|
125
|
+
* only a single signal. Absent sources are ignored, and a lone signal is
|
|
126
|
+
* returned as-is so the common path allocates nothing. Returns `undefined`
|
|
127
|
+
* only when every input is absent, which callers can pass straight through
|
|
128
|
+
* to an optional `signal` parameter.
|
|
129
|
+
*
|
|
130
|
+
* Aborting an input aborts the result (carrying that input's `reason`);
|
|
131
|
+
* nothing propagates back the other way.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* await fetch(url, { signal: combineAbortSignals(req.signal, timeout.signal) });
|
|
135
|
+
*/
|
|
136
|
+
export declare function combineAbortSignals(...signals: (AbortSignal | undefined)[]): AbortSignal | undefined;
|
|
137
|
+
/**
|
|
138
|
+
* Promisified `setTimeout` that wakes up early (and rejects with
|
|
139
|
+
* `signal.reason`) when `signal` aborts mid-wait. Short-circuits to a
|
|
140
|
+
* rejected promise when the signal is already aborted on entry, so the
|
|
141
|
+
* abort path is consistent regardless of whether the wait actually
|
|
142
|
+
* started.
|
|
143
|
+
*
|
|
144
|
+
* Use as the building block for any "wait, but cancel cleanly" pattern -
|
|
145
|
+
* inter-poll backoff, pacing loops, retry timers, long-poll budgets - so
|
|
146
|
+
* cancellation always rejects with the caller's `signal.reason` rather
|
|
147
|
+
* than silently resolving after the timer expires.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* await sleep(250, req.signal);
|
|
151
|
+
*/
|
|
152
|
+
export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
|
package/lib/src/async.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cancellation-aware async primitives: an abortable {@link sleep}, an
|
|
3
|
+
* {@link AbortController} linker ({@link tieAbortSignal}), and a periodic
|
|
4
|
+
* {@link poll} generator. Dependency-free; `poll`'s `"distinct"` filter
|
|
5
|
+
* uses the local {@link deepEqual}.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { deepEqual } from "./object.js";
|
|
10
|
+
/**
|
|
11
|
+
* Async iterable that drives a periodic poll. Each iteration:
|
|
12
|
+
*
|
|
13
|
+
* 1. Builds a {@link PollContext} (`attempt`, `previous`, `signal`,
|
|
14
|
+
* shared `attributes`) and calls `producer(ctx)`; yields the
|
|
15
|
+
* resolved value (subject to `filter`).
|
|
16
|
+
* 2. Evaluates `options.predicate(value, ctx)`; stops when it
|
|
17
|
+
* returns (or resolves to) `false`.
|
|
18
|
+
* 3. Sleeps `options.intervalMs` before the next attempt.
|
|
19
|
+
*
|
|
20
|
+
* The first call runs immediately (no leading sleep) so the consumer
|
|
21
|
+
* sees a value without waiting an interval. Errors thrown by
|
|
22
|
+
* `producer` propagate through the generator.
|
|
23
|
+
*
|
|
24
|
+
* `poll` always creates an internal `AbortController` and exposes
|
|
25
|
+
* `internal.signal` as `ctx.signal`, so producers can rely on a
|
|
26
|
+
* defined signal without a nullish check. The external
|
|
27
|
+
* `options.signal` is tied in, and a `try/finally` aborts the
|
|
28
|
+
* internal signal when the consumer breaks out of the `for await`
|
|
29
|
+
* (or the loop throws), so any producer work still holding the
|
|
30
|
+
* signal sees the cancellation too.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* for await (const msg of poll(
|
|
34
|
+
* async ({ signal }) =>
|
|
35
|
+
* client.genie.getMessage({ ... }, { abortSignal: signal }),
|
|
36
|
+
* {
|
|
37
|
+
* intervalMs: 250,
|
|
38
|
+
* predicate: (m) => !TERMINAL_STATUSES.has(m.status),
|
|
39
|
+
* signal: controller.signal,
|
|
40
|
+
* },
|
|
41
|
+
* )) {
|
|
42
|
+
* render(msg);
|
|
43
|
+
* }
|
|
44
|
+
*/
|
|
45
|
+
export async function* poll(producer, options) {
|
|
46
|
+
const { intervalMs, predicate, signal, attributes, timeoutMs } = options;
|
|
47
|
+
const controller = new AbortController();
|
|
48
|
+
if (signal)
|
|
49
|
+
tieAbortSignal(controller, signal);
|
|
50
|
+
if (timeoutMs !== undefined) {
|
|
51
|
+
tieAbortSignal(controller, AbortSignal.timeout(timeoutMs));
|
|
52
|
+
}
|
|
53
|
+
// Single shared attributes object so writes from one iteration are
|
|
54
|
+
// visible on the next. `{} as A` is safe because either the caller
|
|
55
|
+
// supplied `attributes` (typed) or `A` defaulted to the unknown
|
|
56
|
+
// record shape (in which case `{}` satisfies it).
|
|
57
|
+
const sharedAttributes = attributes ?? {};
|
|
58
|
+
try {
|
|
59
|
+
let previous;
|
|
60
|
+
for (let attempt = 0;; attempt++) {
|
|
61
|
+
controller.signal.throwIfAborted();
|
|
62
|
+
const ctx = {
|
|
63
|
+
attempt,
|
|
64
|
+
previous,
|
|
65
|
+
signal: controller.signal,
|
|
66
|
+
attributes: sharedAttributes,
|
|
67
|
+
};
|
|
68
|
+
const value = await producer(ctx);
|
|
69
|
+
if (options.filter) {
|
|
70
|
+
if (options.filter === "distinct") {
|
|
71
|
+
if (deepEqual(previous, value))
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
else if (!(await options.filter(value, ctx))) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
yield value;
|
|
79
|
+
if (predicate && !(await predicate(value, ctx)))
|
|
80
|
+
return;
|
|
81
|
+
await sleep(intervalMs, controller.signal);
|
|
82
|
+
previous = value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
controller.abort();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Tie a child `AbortController` to a parent signal. The child aborts
|
|
91
|
+
* whenever the parent aborts; aborting the child does not affect the
|
|
92
|
+
* parent (so a fetch-level cancel doesn't tear down the main poll loop).
|
|
93
|
+
*/
|
|
94
|
+
export function tieAbortSignal(child, parent) {
|
|
95
|
+
if (!parent) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
else if (parent.aborted) {
|
|
99
|
+
child.abort(parent.reason);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
parent.addEventListener("abort", () => child.abort(parent.reason), {
|
|
103
|
+
once: true,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Combine several optional cancellation sources into one signal that aborts
|
|
108
|
+
* as soon as any of them does.
|
|
109
|
+
*
|
|
110
|
+
* The usual caller is an operation that has to honor more than one source at
|
|
111
|
+
* once - a caller's own signal (a closed connection, an agent run being
|
|
112
|
+
* cancelled) plus one derived from a timeout - where the awaited I/O accepts
|
|
113
|
+
* only a single signal. Absent sources are ignored, and a lone signal is
|
|
114
|
+
* returned as-is so the common path allocates nothing. Returns `undefined`
|
|
115
|
+
* only when every input is absent, which callers can pass straight through
|
|
116
|
+
* to an optional `signal` parameter.
|
|
117
|
+
*
|
|
118
|
+
* Aborting an input aborts the result (carrying that input's `reason`);
|
|
119
|
+
* nothing propagates back the other way.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* await fetch(url, { signal: combineAbortSignals(req.signal, timeout.signal) });
|
|
123
|
+
*/
|
|
124
|
+
export function combineAbortSignals(...signals) {
|
|
125
|
+
const present = signals.filter((signal) => signal !== undefined);
|
|
126
|
+
if (present.length <= 1)
|
|
127
|
+
return present[0];
|
|
128
|
+
const combined = new AbortController();
|
|
129
|
+
for (const signal of present)
|
|
130
|
+
tieAbortSignal(combined, signal);
|
|
131
|
+
return combined.signal;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Promisified `setTimeout` that wakes up early (and rejects with
|
|
135
|
+
* `signal.reason`) when `signal` aborts mid-wait. Short-circuits to a
|
|
136
|
+
* rejected promise when the signal is already aborted on entry, so the
|
|
137
|
+
* abort path is consistent regardless of whether the wait actually
|
|
138
|
+
* started.
|
|
139
|
+
*
|
|
140
|
+
* Use as the building block for any "wait, but cancel cleanly" pattern -
|
|
141
|
+
* inter-poll backoff, pacing loops, retry timers, long-poll budgets - so
|
|
142
|
+
* cancellation always rejects with the caller's `signal.reason` rather
|
|
143
|
+
* than silently resolving after the timer expires.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* await sleep(250, req.signal);
|
|
147
|
+
*/
|
|
148
|
+
export function sleep(ms, signal) {
|
|
149
|
+
if (signal?.aborted)
|
|
150
|
+
return Promise.reject(signal.reason);
|
|
151
|
+
return new Promise((resolve, reject) => {
|
|
152
|
+
const onAbort = () => {
|
|
153
|
+
clearTimeout(timer);
|
|
154
|
+
reject(signal.reason);
|
|
155
|
+
};
|
|
156
|
+
const timer = setTimeout(() => {
|
|
157
|
+
signal?.removeEventListener("abort", onAbort);
|
|
158
|
+
resolve();
|
|
159
|
+
}, ms);
|
|
160
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRztBQUNILE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFrRnJDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0NHO0FBQ0gsTUFBTSxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsSUFBSSxDQUN6QixRQUE0QixFQUM1QixPQUEwQjtJQUUxQixNQUFNLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUN6RSxNQUFNLFVBQVUsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO0lBQ3pDLElBQUksTUFBTTtRQUFFLGNBQWMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDL0MsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDNUIsY0FBYyxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUNELG1FQUFtRTtJQUNuRSxtRUFBbUU7SUFDbkUsZ0VBQWdFO0lBQ2hFLGtEQUFrRDtJQUNsRCxNQUFNLGdCQUFnQixHQUFHLFVBQVUsSUFBSyxFQUFRLENBQUM7SUFDakQsSUFBSSxDQUFDO1FBQ0gsSUFBSSxRQUF1QixDQUFDO1FBQzVCLEtBQUssSUFBSSxPQUFPLEdBQUcsQ0FBQyxHQUFJLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDbEMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNuQyxNQUFNLEdBQUcsR0FBc0I7Z0JBQzdCLE9BQU87Z0JBQ1AsUUFBUTtnQkFDUixNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07Z0JBQ3pCLFVBQVUsRUFBRSxnQkFBZ0I7YUFDN0IsQ0FBQztZ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LENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzdELENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2FuY2VsbGF0aW9uLWF3YXJlIGFzeW5jIHByaW1pdGl2ZXM6IGFuIGFib3J0YWJsZSB7QGxpbmsgc2xlZXB9LCBhblxuICoge0BsaW5rIEFib3J0Q29udHJvbGxlcn0gbGlua2VyICh7QGxpbmsgdGllQWJvcnRTaWduYWx9KSwgYW5kIGEgcGVyaW9kaWNcbiAqIHtAbGluayBwb2xsfSBnZW5lcmF0b3IuIERlcGVuZGVuY3ktZnJlZTsgYHBvbGxgJ3MgYFwiZGlzdGluY3RcImAgZmlsdGVyXG4gKiB1c2VzIHRoZSBsb2NhbCB7QGxpbmsgZGVlcEVxdWFsfS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7IGRlZXBFcXVhbCB9IGZyb20gXCIuL29iamVjdFwiO1xuXG4vKipcbiAqIFBlci1pdGVyYXRpb24gY29udGV4dCBoYW5kZWQgdG8ge0BsaW5rIFBvbGxQcm9kdWNlcn0gYW5kIHRoZVxuICogcHJlZGljYXRlIG9uIGVhY2ggc3RlcCBvZiBhIHtAbGluayBwb2xsfSBsb29wLiBCdW5kbGVzIHRoZVxuICogaXRlcmF0aW9uIG1ldGFkYXRhIHNvIHRoZSBjYWxsIHNpZ25hdHVyZXMgc3RheSBzdGFibGUgYXMgYHBvbGxgXG4gKiBncm93cyBhZGRpdGlvbmFsIGZpZWxkcy5cbiAqXG4gKiBgc2lnbmFsYCBpcyBvd25lZCBieSBgcG9sbGA6IGl0IHRyYWNrcyB0aGUgZXh0ZXJuYWxcbiAqIGBQb2xsT3B0aW9ucy5zaWduYWxgICh3aGVuIHN1cHBsaWVkKSBhbmQgYWxzbyBmaXJlcyB3aGVuIHRoZVxuICogY29uc3VtZXIgYnJlYWtzIG91dCBvZiB0aGUgbG9vcCwgc28gcHJvZHVjZXJzIGNhbiBmb3J3YXJkIGl0IHRvXG4gKiBhbnkgaW4tZmxpZ2h0IHdvcmsgKGBmZXRjaGAsIFNESyBjYWxscywgZXRjLikgYW5kIGhhdmUgYSBzaW5nbGVcbiAqIGNhbmNlbGxhdGlvbiBzb3VyY2UgdGVhciBkb3duIGJvdGggdGhlIHJlcXVlc3QgYW5kIHRoZSBsb29wLlxuICpcbiAqIGBhdHRyaWJ1dGVzYCBpcyBhIG11dGFibGUgc2NyYXRjaHBhZCBzaGFyZWQgYWNyb3NzIGV2ZXJ5XG4gKiBpdGVyYXRpb24gb2YgYSBzaW5nbGUgYHBvbGxgIHJ1bi4gVGhlIHNhbWUgb2JqZWN0IHJlZmVyZW5jZSBpc1xuICogcGFzc2VkIGVhY2ggY2FsbCBzbyB3cml0ZXMgZnJvbSBvbmUgaXRlcmF0aW9uIGFyZSB2aXNpYmxlIHRvIHRoZVxuICogbmV4dCAtIHVzZWZ1bCBmb3Igc3Rhc2hpbmcgcGVyLWxvb3Agc3RhdGUgKHJldHJ5IGNvdW50ZXJzLCBzdGFydFxuICogdGltZXN0YW1wcywgYW55dGhpbmcgeW91J2Qgb3RoZXJ3aXNlIGNsb3NlIG92ZXIgdmlhIGEgbGV0KS5cbiAqIEdlbmVyaWMgYEFgIGxldHMgY2FsbGVycyB0eXBlIHRoZSBiYWc7IGRlZmF1bHRzIHRvXG4gKiBgUmVjb3JkPHN0cmluZywgdW5rbm93bj5gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvbGxDb250ZXh0PFQsIEEgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ge1xuICAvKiogWmVyby1iYXNlZCBpdGVyYXRpb24gaW5kZXggKGAwYCBvbiB0aGUgZmlyc3QgY2FsbCkuICovXG4gIGF0dGVtcHQ6IG51bWJlcjtcbiAgLyoqIFZhbHVlIHlpZWxkZWQgb24gdGhlIHByaW9yIGl0ZXJhdGlvbjsgYHVuZGVmaW5lZGAgb24gdGhlIGZpcnN0LiAqL1xuICBwcmV2aW91czogVCB8IHVuZGVmaW5lZDtcbiAgLyoqIENhbmNlbGxhdGlvbiBoYW5kbGUuIEFsd2F5cyBkZWZpbmVkOyBmb3J3YXJkIHRvIGluLWZsaWdodCB3b3JrLiAqL1xuICBzaWduYWw6IEFib3J0U2lnbmFsO1xuICAvKiogUGVyLXJ1biBtdXRhYmxlIHNjcmF0Y2hwYWQgc2hhcmVkIGFjcm9zcyBpdGVyYXRpb25zLiAqL1xuICBhdHRyaWJ1dGVzOiBBO1xufVxuXG4vKiogT25lIHN0ZXAgb2YgYSB7QGxpbmsgcG9sbH0gbG9vcC4gU2VlIHtAbGluayBQb2xsQ29udGV4dH0uICovXG5leHBvcnQgdHlwZSBQb2xsUHJvZHVjZXI8VCwgQSA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+PiA9IChcbiAgY3R4OiBQb2xsQ29udGV4dDxULCBBPixcbikgPT4gVCB8IFByb21pc2VMaWtlPFQ+O1xuXG5leHBvcnQgaW50ZXJmYWNlIFBvbGxPcHRpb25zPFQsIEEgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ge1xuICAvKiogTWlsbGlzZWNvbmRzIHRvIHdhaXQgYmV0d2VlbiBwb2xscy4gKi9cbiAgaW50ZXJ2YWxNczogbnVtYmVyO1xuICAvKipcbiAgICogUHJlZGljYXRlIGV2YWx1YXRlZCBhZ2FpbnN0IGVhY2ggeWllbGRlZCB2YWx1ZTogcmV0dXJuIGB0cnVlYCB0b1xuICAgKiBrZWVwIGl0LCBgZmFsc2VgIHRvIHNraXAgaXQgKHdpdGhvdXQgc3RvcHBpbmcgdGhlIGxvb3ApLiBNYXkgYmVcbiAgICogc3luYyBvciBhc3luYyAtIGEgYFByb21pc2VMaWtlPGJvb2xlYW4+YCBpcyBhd2FpdGVkIGJlZm9yZSB0aGVcbiAgICogZGVjaXNpb24gaXMgbWFkZS4gUmVjZWl2ZXMgdGhlIHNhbWUge0BsaW5rIFBvbGxDb250ZXh0fSBhcyB0aGVcbiAgICogcHJvZHVjZXIgKHNhbWUgYHNpZ25hbGAsIHNhbWUgYGF0dHJpYnV0ZXNgIGJhZykuIFRoZSBzcGVjaWFsXG4gICAqIHZhbHVlIGBcImRpc3RpbmN0XCJgIHNraXBzIGEgdmFsdWUgdGhhdCBkZWVwLWVxdWFscyB0aGUgcHJldmlvdXNcbiAgICogb25lLlxuICAgKi9cbiAgZmlsdGVyPzogKCh2YWx1ZTogVCwgY3R4OiBQb2xsQ29udGV4dDxULCBBPikgPT4gYm9vbGVhbiB8IFByb21pc2VMaWtlPGJvb2xlYW4+KSB8IFwiZGlzdGluY3RcIjtcbiAgLyoqXG4gICAqIFByZWRpY2F0ZSBldmFsdWF0ZWQgYWdhaW5zdCBlYWNoIHlpZWxkZWQgdmFsdWU6IHJldHVybiBgdHJ1ZWAgdG9cbiAgICoga2VlcCBwb2xsaW5nLCBgZmFsc2VgIHRvIHN0b3AuIE1heSBiZSBzeW5jIG9yIGFzeW5jLiBPbWl0IHRvIHBvbGxcbiAgICogZm9yZXZlciAodGhlIGNvbnN1bWVyIHN0b3BzIGJ5IGJyZWFraW5nIG91dCBvZiB0aGUgbG9vcCBvciBieVxuICAgKiBhYm9ydGluZyBgc2lnbmFsYCkuXG4gICAqL1xuICBwcmVkaWNhdGU/OiAodmFsdWU6IFQsIGN0eDogUG9sbENvbnRleHQ8VCwgQT4pID0+IGJvb2xlYW4gfCBQcm9taXNlTGlrZTxib29sZWFuPjtcbiAgLyoqXG4gICAqIEV4dGVybmFsIGNhbmNlbGxhdGlvbiBoYW5kbGUuIFRpZWQgaW50byB0aGUgaW50ZXJuYWwgc2lnbmFsIHRoYXRcbiAgICogYHBvbGxgIGhhbmRzIHRvIGBwcm9kdWNlcmAsIHNvIGFib3J0aW5nIGl0IHRlYXJzIGRvd24gYm90aCB0aGVcbiAgICogaW4tZmxpZ2h0IHJlcXVlc3QgYW5kIHRoZSBpbnRlci1wb2xsIHNsZWVwLlxuICAgKi9cbiAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIC8qKlxuICAgKiBIYXJkIHVwcGVyIGJvdW5kIG9uIHRoZSB0b3RhbCBsaWZldGltZSBvZiB0aGUgcG9sbCBsb29wLCBpblxuICAgKiBtaWxsaXNlY29uZHMuIFdoZW4gdGhlIGJ1ZGdldCBlbGFwc2VzLCBgcG9sbGAgYWJvcnRzIGl0cyBpbnRlcm5hbFxuICAgKiBzaWduYWwgc28gdGhlIGluLWZsaWdodCBwcm9kdWNlciBhbmQgaW50ZXItcG9sbCBzbGVlcCBib3RoIHRlYXJcbiAgICogZG93biBwcm9tcHRseSwgYW5kIHRoZSBsb29wIHRocm93cyB0aGUgYFRpbWVvdXRFcnJvcmBcbiAgICogYERPTUV4Y2VwdGlvbmAgcHJvZHVjZWQgYnkgYEFib3J0U2lnbmFsLnRpbWVvdXQodGltZW91dE1zKWAuIFRoZVxuICAgKiBidWRnZXQgc3RhcnRzIHRpY2tpbmcgdGhlIG1vbWVudCB0aGUgZ2VuZXJhdG9yIGlzIGNyZWF0ZWQuXG4gICAqL1xuICB0aW1lb3V0TXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBJbml0aWFsIHZhbHVlIGZvciBgY3R4LmF0dHJpYnV0ZXNgLiBEZWZhdWx0cyB0byBge31gLiBUaGUgc2FtZVxuICAgKiBvYmplY3QgaXMgcmV1c2VkIGFjcm9zcyBpdGVyYXRpb25zLCBzbyBjYWxsZXJzIGNhbiBwcmUtcG9wdWxhdGVcbiAgICogZmllbGRzICh0aW1lcnMsIHJldHJ5IGNvdW50ZXJzLCBldGMuKSBhbmQgdGhlIHByb2R1Y2VyIC9cbiAgICogcHJlZGljYXRlIGNhbiBtdXRhdGUgdGhlbSBpbiBwbGFjZS5cbiAgICovXG4gIGF0dHJpYnV0ZXM/OiBBO1xufVxuXG4vKipcbiAqIEFzeW5jIGl0ZXJhYmxlIHRoYXQgZHJpdmVzIGEgcGVyaW9kaWMgcG9sbC4gRWFjaCBpdGVyYXRpb246XG4gKlxuICogICAxLiBCdWlsZHMgYSB7QGxpbmsgUG9sbENvbnRleHR9IChgYXR0ZW1wdGAsIGBwcmV2aW91c2AsIGBzaWduYWxgLFxuICogICAgICBzaGFyZWQgYGF0dHJpYnV0ZXNgKSBhbmQgY2FsbHMgYHByb2R1Y2VyKGN0eClgOyB5aWVsZHMgdGhlXG4gKiAgICAgIHJlc29sdmVkIHZhbHVlIChzdWJqZWN0IHRvIGBmaWx0ZXJgKS5cbiAqICAgMi4gRXZhbHVhdGVzIGBvcHRpb25zLnByZWRpY2F0ZSh2YWx1ZSwgY3R4KWA7IHN0b3BzIHdoZW4gaXRcbiAqICAgICAgcmV0dXJucyAob3IgcmVzb2x2ZXMgdG8pIGBmYWxzZWAuXG4gKiAgIDMuIFNsZWVwcyBgb3B0aW9ucy5pbnRlcnZhbE1zYCBiZWZvcmUgdGhlIG5leHQgYXR0ZW1wdC5cbiAqXG4gKiBUaGUgZmlyc3QgY2FsbCBydW5zIGltbWVkaWF0ZWx5IChubyBsZWFkaW5nIHNsZWVwKSBzbyB0aGUgY29uc3VtZXJcbiAqIHNlZXMgYSB2YWx1ZSB3aXRob3V0IHdhaXRpbmcgYW4gaW50ZXJ2YWwuIEVycm9ycyB0aHJvd24gYnlcbiAqIGBwcm9kdWNlcmAgcHJvcGFnYXRlIHRocm91Z2ggdGhlIGdlbmVyYXRvci5cbiAqXG4gKiBgcG9sbGAgYWx3YXlzIGNyZWF0ZXMgYW4gaW50ZXJuYWwgYEFib3J0Q29udHJvbGxlcmAgYW5kIGV4cG9zZXNcbiAqIGBpbnRlcm5hbC5zaWduYWxgIGFzIGBjdHguc2lnbmFsYCwgc28gcHJvZHVjZXJzIGNhbiByZWx5IG9uIGFcbiAqIGRlZmluZWQgc2lnbmFsIHdpdGhvdXQgYSBudWxsaXNoIGNoZWNrLiBUaGUgZXh0ZXJuYWxcbiAqIGBvcHRpb25zLnNpZ25hbGAgaXMgdGllZCBpbiwgYW5kIGEgYHRyeS9maW5hbGx5YCBhYm9ydHMgdGhlXG4gKiBpbnRlcm5hbCBzaWduYWwgd2hlbiB0aGUgY29uc3VtZXIgYnJlYWtzIG91dCBvZiB0aGUgYGZvciBhd2FpdGBcbiAqIChvciB0aGUgbG9vcCB0aHJvd3MpLCBzbyBhbnkgcHJvZHVjZXIgd29yayBzdGlsbCBob2xkaW5nIHRoZVxuICogc2lnbmFsIHNlZXMgdGhlIGNhbmNlbGxhdGlvbiB0b28uXG4gKlxuICogQGV4YW1wbGVcbiAqIGZvciBhd2FpdCAoY29uc3QgbXNnIG9mIHBvbGwoXG4gKiAgIGFzeW5jICh7IHNpZ25hbCB9KSA9PlxuICogICAgIGNsaWVudC5nZW5pZS5nZXRNZXNzYWdlKHsgLi4uIH0sIHsgYWJvcnRTaWduYWw6IHNpZ25hbCB9KSxcbiAqICAge1xuICogICAgIGludGVydmFsTXM6IDI1MCxcbiAqICAgICBwcmVkaWNhdGU6IChtKSA9PiAhVEVSTUlOQUxfU1RBVFVTRVMuaGFzKG0uc3RhdHVzKSxcbiAqICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICogICB9LFxuICogKSkge1xuICogICByZW5kZXIobXNnKTtcbiAqIH1cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uKiBwb2xsPFQsIEEgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gIHByb2R1Y2VyOiBQb2xsUHJvZHVjZXI8VCwgQT4sXG4gIG9wdGlvbnM6IFBvbGxPcHRpb25zPFQsIEE+LFxuKTogQXN5bmNHZW5lcmF0b3I8VCwgdm9pZCwgdm9pZD4ge1xuICBjb25zdCB7IGludGVydmFsTXMsIHByZWRpY2F0ZSwgc2lnbmFsLCBhdHRyaWJ1dGVzLCB0aW1lb3V0TXMgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gIGlmIChzaWduYWwpIHRpZUFib3J0U2lnbmFsKGNvbnRyb2xsZXIsIHNpZ25hbCk7XG4gIGlmICh0aW1lb3V0TXMgIT09IHVuZGVmaW5lZCkge1xuICAgIHRpZUFib3J0U2lnbmFsKGNvbnRyb2xsZXIsIEFib3J0U2lnbmFsLnRpbWVvdXQodGltZW91dE1zKSk7XG4gIH1cbiAgLy8gU2luZ2xlIHNoYXJlZCBhdHRyaWJ1dGVzIG9iamVjdCBzbyB3cml0ZXMgZnJvbSBvbmUgaXRlcmF0aW9uIGFyZVxuICAvLyB2aXNpYmxlIG9uIHRoZSBuZXh0LiBge30gYXMgQWAgaXMgc2FmZSBiZWNhdXNlIGVpdGhlciB0aGUgY2FsbGVyXG4gIC8vIHN1cHBsaWVkIGBhdHRyaWJ1dGVzYCAodHlwZWQpIG9yIGBBYCBkZWZhdWx0ZWQgdG8gdGhlIHVua25vd25cbiAgLy8gcmVjb3JkIHNoYXBlIChpbiB3aGljaCBjYXNlIGB7fWAgc2F0aXNmaWVzIGl0KS5cbiAgY29uc3Qgc2hhcmVkQXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMgPz8gKHt9IGFzIEEpO1xuICB0cnkge1xuICAgIGxldCBwcmV2aW91czogVCB8IHVuZGVmaW5lZDtcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgOyBhdHRlbXB0KyspIHtcbiAgICAgIGNvbnRyb2xsZXIuc2lnbmFsLnRocm93SWZBYm9ydGVkKCk7XG4gICAgICBjb25zdCBjdHg6IFBvbGxDb250ZXh0PFQsIEE+ID0ge1xuICAgICAgICBhdHRlbXB0LFxuICAgICAgICBwcmV2aW91cyxcbiAgICAgICAgc2lnbmFsOiBjb250cm9sbGVyLnNpZ25hbCxcbiAgICAgICAgYXR0cmlidXRlczogc2hhcmVkQXR0cmlidXRlcyxcbiAgICAgIH07XG4gICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHByb2R1Y2VyKGN0eCk7XG4gICAgICBpZiAob3B0aW9ucy5maWx0ZXIpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZmlsdGVyID09PSBcImRpc3RpbmN0XCIpIHtcbiAgICAgICAgICBpZiAoZGVlcEVxdWFsKHByZXZpb3VzLCB2YWx1ZSkpIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2UgaWYgKCEoYXdhaXQgb3B0aW9ucy5maWx0ZXIodmFsdWUsIGN0eCkpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHlpZWxkIHZhbHVlO1xuICAgICAgaWYgKHByZWRpY2F0ZSAmJiAhKGF3YWl0IHByZWRpY2F0ZSh2YWx1ZSwgY3R4KSkpIHJldHVybjtcbiAgICAgIGF3YWl0IHNsZWVwKGludGVydmFsTXMsIGNvbnRyb2xsZXIuc2lnbmFsKTtcbiAgICAgIHByZXZpb3VzID0gdmFsdWU7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgfVxufVxuXG4vKipcbiAqIFRpZSBhIGNoaWxkIGBBYm9ydENvbnRyb2xsZXJgIHRvIGEgcGFyZW50IHNpZ25hbC4gVGhlIGNoaWxkIGFib3J0c1xuICogd2hlbmV2ZXIgdGhlIHBhcmVudCBhYm9ydHM7IGFib3J0aW5nIHRoZSBjaGlsZCBkb2VzIG5vdCBhZmZlY3QgdGhlXG4gKiBwYXJlbnQgKHNvIGEgZmV0Y2gtbGV2ZWwgY2FuY2VsIGRvZXNuJ3QgdGVhciBkb3duIHRoZSBtYWluIHBvbGwgbG9vcCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0aWVBYm9ydFNpZ25hbChjaGlsZDogQWJvcnRDb250cm9sbGVyLCBwYXJlbnQ/OiBBYm9ydFNpZ25hbCk6IHZvaWQge1xuICBpZiAoIXBhcmVudCkge1xuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChwYXJlbnQuYWJvcnRlZCkge1xuICAgIGNoaWxkLmFib3J0KHBhcmVudC5yZWFzb24pO1xuICAgIHJldHVybjtcbiAgfVxuICBwYXJlbnQuYWRkRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsICgpID0+IGNoaWxkLmFib3J0KHBhcmVudC5yZWFzb24pLCB7XG4gICAgb25jZTogdHJ1ZSxcbiAgfSk7XG59XG5cbi8qKlxuICogQ29tYmluZSBzZXZlcmFsIG9wdGlvbmFsIGNhbmNlbGxhdGlvbiBzb3VyY2VzIGludG8gb25lIHNpZ25hbCB0aGF0IGFib3J0c1xuICogYXMgc29vbiBhcyBhbnkgb2YgdGhlbSBkb2VzLlxuICpcbiAqIFRoZSB1c3VhbCBjYWxsZXIgaXMgYW4gb3BlcmF0aW9uIHRoYXQgaGFzIHRvIGhvbm9yIG1vcmUgdGhhbiBvbmUgc291cmNlIGF0XG4gKiBvbmNlIC0gYSBjYWxsZXIncyBvd24gc2lnbmFsIChhIGNsb3NlZCBjb25uZWN0aW9uLCBhbiBhZ2VudCBydW4gYmVpbmdcbiAqIGNhbmNlbGxlZCkgcGx1cyBvbmUgZGVyaXZlZCBmcm9tIGEgdGltZW91dCAtIHdoZXJlIHRoZSBhd2FpdGVkIEkvTyBhY2NlcHRzXG4gKiBvbmx5IGEgc2luZ2xlIHNpZ25hbC4gQWJzZW50IHNvdXJjZXMgYXJlIGlnbm9yZWQsIGFuZCBhIGxvbmUgc2lnbmFsIGlzXG4gKiByZXR1cm5lZCBhcy1pcyBzbyB0aGUgY29tbW9uIHBhdGggYWxsb2NhdGVzIG5vdGhpbmcuIFJldHVybnMgYHVuZGVmaW5lZGBcbiAqIG9ubHkgd2hlbiBldmVyeSBpbnB1dCBpcyBhYnNlbnQsIHdoaWNoIGNhbGxlcnMgY2FuIHBhc3Mgc3RyYWlnaHQgdGhyb3VnaFxuICogdG8gYW4gb3B0aW9uYWwgYHNpZ25hbGAgcGFyYW1ldGVyLlxuICpcbiAqIEFib3J0aW5nIGFuIGlucHV0IGFib3J0cyB0aGUgcmVzdWx0IChjYXJyeWluZyB0aGF0IGlucHV0J3MgYHJlYXNvbmApO1xuICogbm90aGluZyBwcm9wYWdhdGVzIGJhY2sgdGhlIG90aGVyIHdheS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYXdhaXQgZmV0Y2godXJsLCB7IHNpZ25hbDogY29tYmluZUFib3J0U2lnbmFscyhyZXEuc2lnbmFsLCB0aW1lb3V0LnNpZ25hbCkgfSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21iaW5lQWJvcnRTaWduYWxzKFxuICAuLi5zaWduYWxzOiAoQWJvcnRTaWduYWwgfCB1bmRlZmluZWQpW11cbik6IEFib3J0U2lnbmFsIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcHJlc2VudCA9IHNpZ25hbHMuZmlsdGVyKChzaWduYWwpOiBzaWduYWwgaXMgQWJvcnRTaWduYWwgPT4gc2lnbmFsICE9PSB1bmRlZmluZWQpO1xuICBpZiAocHJlc2VudC5sZW5ndGggPD0gMSkgcmV0dXJuIHByZXNlbnRbMF07XG4gIGNvbnN0IGNvbWJpbmVkID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBmb3IgKGNvbnN0IHNpZ25hbCBvZiBwcmVzZW50KSB0aWVBYm9ydFNpZ25hbChjb21iaW5lZCwgc2lnbmFsKTtcbiAgcmV0dXJuIGNvbWJpbmVkLnNpZ25hbDtcbn1cblxuLyoqXG4gKiBQcm9taXNpZmllZCBgc2V0VGltZW91dGAgdGhhdCB3YWtlcyB1cCBlYXJseSAoYW5kIHJlamVjdHMgd2l0aFxuICogYHNpZ25hbC5yZWFzb25gKSB3aGVuIGBzaWduYWxgIGFib3J0cyBtaWQtd2FpdC4gU2hvcnQtY2lyY3VpdHMgdG8gYVxuICogcmVqZWN0ZWQgcHJvbWlzZSB3aGVuIHRoZSBzaWduYWwgaXMgYWxyZWFkeSBhYm9ydGVkIG9uIGVudHJ5LCBzbyB0aGVcbiAqIGFib3J0IHBhdGggaXMgY29uc2lzdGVudCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlIHdhaXQgYWN0dWFsbHlcbiAqIHN0YXJ0ZWQuXG4gKlxuICogVXNlIGFzIHRoZSBidWlsZGluZyBibG9jayBmb3IgYW55IFwid2FpdCwgYnV0IGNhbmNlbCBjbGVhbmx5XCIgcGF0dGVybiAtXG4gKiBpbnRlci1wb2xsIGJhY2tvZmYsIHBhY2luZyBsb29wcywgcmV0cnkgdGltZXJzLCBsb25nLXBvbGwgYnVkZ2V0cyAtIHNvXG4gKiBjYW5jZWxsYXRpb24gYWx3YXlzIHJlamVjdHMgd2l0aCB0aGUgY2FsbGVyJ3MgYHNpZ25hbC5yZWFzb25gIHJhdGhlclxuICogdGhhbiBzaWxlbnRseSByZXNvbHZpbmcgYWZ0ZXIgdGhlIHRpbWVyIGV4cGlyZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGF3YWl0IHNsZWVwKDI1MCwgcmVxLnNpZ25hbCk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyLCBzaWduYWw/OiBBYm9ydFNpZ25hbCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoc2lnbmFsPy5hYm9ydGVkKSByZXR1cm4gUHJvbWlzZS5yZWplY3Qoc2lnbmFsLnJlYXNvbik7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3Qgb25BYm9ydCA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICByZWplY3Qoc2lnbmFsIS5yZWFzb24pO1xuICAgIH07XG4gICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHNpZ25hbD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQpO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0sIG1zKTtcbiAgICBzaWduYWw/LmFkZEV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBvbkFib3J0LCB7IG9uY2U6IHRydWUgfSk7XG4gIH0pO1xufVxuIl19
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe brand contract, defaults, and LLM serialization helpers.
|
|
3
|
+
*
|
|
4
|
+
* Asset values are intentionally strings: they may be relative file paths,
|
|
5
|
+
* package exports, data URLs, or network URLs depending on the consumer.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
export declare const DEFAULT_BRAND_ASSETS: {
|
|
11
|
+
readonly icon: {
|
|
12
|
+
readonly light: "@dbx-tools/ui-branding/assets/icon-light.svg";
|
|
13
|
+
readonly dark: "@dbx-tools/ui-branding/assets/icon-dark.svg";
|
|
14
|
+
};
|
|
15
|
+
readonly logo: {
|
|
16
|
+
readonly light: "@dbx-tools/ui-branding/assets/logo-light.svg";
|
|
17
|
+
readonly dark: "@dbx-tools/ui-branding/assets/logo-dark.svg";
|
|
18
|
+
};
|
|
19
|
+
readonly favicon: "@dbx-tools/ui-branding/assets/icon-light.svg";
|
|
20
|
+
};
|
|
21
|
+
export declare const BrandAssetSetSchema: z.ZodObject<{
|
|
22
|
+
light: z.ZodString;
|
|
23
|
+
dark: z.ZodOptional<z.ZodString>;
|
|
24
|
+
}, z.core.$strict>;
|
|
25
|
+
export declare const BrandColorsSchema: z.ZodPrefault<z.ZodObject<{
|
|
26
|
+
primary: z.ZodDefault<z.ZodString>;
|
|
27
|
+
primaryHover: z.ZodDefault<z.ZodString>;
|
|
28
|
+
accent: z.ZodDefault<z.ZodString>;
|
|
29
|
+
foreground: z.ZodDefault<z.ZodString>;
|
|
30
|
+
background: z.ZodDefault<z.ZodString>;
|
|
31
|
+
surface: z.ZodDefault<z.ZodString>;
|
|
32
|
+
muted: z.ZodDefault<z.ZodString>;
|
|
33
|
+
border: z.ZodDefault<z.ZodString>;
|
|
34
|
+
}, z.core.$strict>>;
|
|
35
|
+
export declare const BrandVoiceSchema: z.ZodPrefault<z.ZodObject<{
|
|
36
|
+
audience: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
37
|
+
tone: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
38
|
+
principles: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
39
|
+
avoid: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
40
|
+
}, z.core.$strict>>;
|
|
41
|
+
export declare const BrandContextSchema: z.ZodObject<{
|
|
42
|
+
schemaVersion: z.ZodDefault<z.ZodLiteral<"1">>;
|
|
43
|
+
name: z.ZodDefault<z.ZodString>;
|
|
44
|
+
shortName: z.ZodDefault<z.ZodString>;
|
|
45
|
+
tagline: z.ZodDefault<z.ZodString>;
|
|
46
|
+
description: z.ZodDefault<z.ZodString>;
|
|
47
|
+
assets: z.ZodDefault<z.ZodObject<{
|
|
48
|
+
icon: z.ZodDefault<z.ZodObject<{
|
|
49
|
+
light: z.ZodString;
|
|
50
|
+
dark: z.ZodOptional<z.ZodString>;
|
|
51
|
+
}, z.core.$strict>>;
|
|
52
|
+
logo: z.ZodDefault<z.ZodObject<{
|
|
53
|
+
light: z.ZodString;
|
|
54
|
+
dark: z.ZodOptional<z.ZodString>;
|
|
55
|
+
}, z.core.$strict>>;
|
|
56
|
+
favicon: z.ZodDefault<z.ZodString>;
|
|
57
|
+
}, z.core.$strict>>;
|
|
58
|
+
colors: z.ZodPrefault<z.ZodObject<{
|
|
59
|
+
primary: z.ZodDefault<z.ZodString>;
|
|
60
|
+
primaryHover: z.ZodDefault<z.ZodString>;
|
|
61
|
+
accent: z.ZodDefault<z.ZodString>;
|
|
62
|
+
foreground: z.ZodDefault<z.ZodString>;
|
|
63
|
+
background: z.ZodDefault<z.ZodString>;
|
|
64
|
+
surface: z.ZodDefault<z.ZodString>;
|
|
65
|
+
muted: z.ZodDefault<z.ZodString>;
|
|
66
|
+
border: z.ZodDefault<z.ZodString>;
|
|
67
|
+
}, z.core.$strict>>;
|
|
68
|
+
typography: z.ZodPrefault<z.ZodObject<{
|
|
69
|
+
sans: z.ZodDefault<z.ZodString>;
|
|
70
|
+
mono: z.ZodDefault<z.ZodString>;
|
|
71
|
+
}, z.core.$strict>>;
|
|
72
|
+
voice: z.ZodPrefault<z.ZodObject<{
|
|
73
|
+
audience: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
74
|
+
tone: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
75
|
+
principles: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
76
|
+
avoid: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
77
|
+
}, z.core.$strict>>;
|
|
78
|
+
links: z.ZodDefault<z.ZodObject<{
|
|
79
|
+
website: z.ZodOptional<z.ZodString>;
|
|
80
|
+
repository: z.ZodOptional<z.ZodString>;
|
|
81
|
+
documentation: z.ZodOptional<z.ZodString>;
|
|
82
|
+
}, z.core.$strict>>;
|
|
83
|
+
extensions: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
84
|
+
}, z.core.$strict>;
|
|
85
|
+
export type BrandContext = z.output<typeof BrandContextSchema>;
|
|
86
|
+
export type BrandContextInput = z.input<typeof BrandContextSchema>;
|
|
87
|
+
export type BrandAssetSet = z.output<typeof BrandAssetSetSchema>;
|
|
88
|
+
/** Validate input and fill every dbx tools default. */
|
|
89
|
+
export declare function parseBrandContext(input?: unknown): BrandContext;
|
|
90
|
+
export declare const defaultBrandContext: BrandContext;
|
|
91
|
+
/** JSON Schema representation suitable for structured-output and tool definitions. */
|
|
92
|
+
export declare function brandContextJsonSchema(): Record<string, unknown>;
|
|
93
|
+
/** Stable prompt block for an LLM that needs to write or design in this brand. */
|
|
94
|
+
export declare function brandContextPrompt(context?: BrandContext): string;
|