@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 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>;
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRztBQUNILE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFrRnJDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0NHO0FBQ0gsTUFBTSxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsSUFBSSxDQUN6QixRQUE0QixFQUM1QixPQUEwQjtJQUUxQixNQUFNLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUN6RSxNQUFNLFVBQVUsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO0lBQ3pDLElBQUksTUFBTTtRQUFFLGNBQWMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDL0MsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDNUIsY0FBYyxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUNELG1FQUFtRTtJQUNuRSxtRUFBbUU7SUFDbkUsZ0VBQWdFO0lBQ2hFLGtEQUFrRDtJQUNsRCxNQUFNLGdCQUFnQixHQUFHLFVBQVUsSUFBSyxFQUFRLENBQUM7SUFDakQsSUFBSSxDQUFDO1FBQ0gsSUFBSSxRQUF1QixDQUFDO1FBQzVCLEtBQUssSUFBSSxPQUFPLEdBQUcsQ0FBQyxHQUFJLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDbEMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNuQyxNQUFNLEdBQUcsR0FBc0I7Z0JBQzdCLE9BQU87Z0JBQ1AsUUFBUTtnQkFDUixNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07Z0JBQ3pCLFVBQVUsRUFBRSxnQkFBZ0I7YUFDN0IsQ0FBQztZQUNGLE1BQU0sS0FBSyxHQUFHLE1BQU0sUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2xDLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNuQixJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssVUFBVSxFQUFFLENBQUM7b0JBQ2xDLElBQUksU0FBUyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUM7d0JBQUUsU0FBUztnQkFDM0MsQ0FBQztxQkFBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDL0MsU0FBUztnQkFDWCxDQUFDO1lBQ0gsQ0FBQztZQUNELE1BQU0sS0FBSyxDQUFDO1lBQ1osSUFBSSxTQUFTLElBQUksQ0FBQyxDQUFDLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFBRSxPQUFPO1lBQ3hELE1BQU0sS0FBSyxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0MsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQztZQUFTLENBQUM7UUFDVCxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDckIsQ0FBQztBQUNILENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUFzQixFQUFFLE1BQW9CO0lBQ3pFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE9BQU87SUFDVCxDQUFDO1NBQU0sSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDMUIsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0IsT0FBTztJQUNULENBQUM7SUFDRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQ2pFLElBQUksRUFBRSxJQUFJO0tBQ1gsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FDakMsR0FBRyxPQUFvQztJQUV2QyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxFQUF5QixFQUFFLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDO0lBQ3hGLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDO1FBQUUsT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztJQUN2QyxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU87UUFBRSxjQUFjLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQy9ELE9BQU8sUUFBUSxDQUFDLE1BQU0sQ0FBQztBQUN6QixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLFVBQVUsS0FBSyxDQUFDLEVBQVUsRUFBRSxNQUFvQjtJQUNwRCxJQUFJLE1BQU0sRUFBRSxPQUFPO1FBQUUsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxRCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ3JDLE1BQU0sT0FBTyxHQUFHLEdBQVMsRUFBRTtZQUN6QixZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEIsTUFBTSxDQUFDLE1BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QixDQUFDLENBQUM7UUFDRixNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQzVCLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDOUMsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDUCxNQUFNLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzdELENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2FuY2VsbGF0aW9uLWF3YXJlIGFzeW5jIHByaW1pdGl2ZXM6IGFuIGFib3J0YWJsZSB7QGxpbmsgc2xlZXB9LCBhblxuICoge0BsaW5rIEFib3J0Q29udHJvbGxlcn0gbGlua2VyICh7QGxpbmsgdGllQWJvcnRTaWduYWx9KSwgYW5kIGEgcGVyaW9kaWNcbiAqIHtAbGluayBwb2xsfSBnZW5lcmF0b3IuIERlcGVuZGVuY3ktZnJlZTsgYHBvbGxgJ3MgYFwiZGlzdGluY3RcImAgZmlsdGVyXG4gKiB1c2VzIHRoZSBsb2NhbCB7QGxpbmsgZGVlcEVxdWFsfS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7IGRlZXBFcXVhbCB9IGZyb20gXCIuL29iamVjdFwiO1xuXG4vKipcbiAqIFBlci1pdGVyYXRpb24gY29udGV4dCBoYW5kZWQgdG8ge0BsaW5rIFBvbGxQcm9kdWNlcn0gYW5kIHRoZVxuICogcHJlZGljYXRlIG9uIGVhY2ggc3RlcCBvZiBhIHtAbGluayBwb2xsfSBsb29wLiBCdW5kbGVzIHRoZVxuICogaXRlcmF0aW9uIG1ldGFkYXRhIHNvIHRoZSBjYWxsIHNpZ25hdHVyZXMgc3RheSBzdGFibGUgYXMgYHBvbGxgXG4gKiBncm93cyBhZGRpdGlvbmFsIGZpZWxkcy5cbiAqXG4gKiBgc2lnbmFsYCBpcyBvd25lZCBieSBgcG9sbGA6IGl0IHRyYWNrcyB0aGUgZXh0ZXJuYWxcbiAqIGBQb2xsT3B0aW9ucy5zaWduYWxgICh3aGVuIHN1cHBsaWVkKSBhbmQgYWxzbyBmaXJlcyB3aGVuIHRoZVxuICogY29uc3VtZXIgYnJlYWtzIG91dCBvZiB0aGUgbG9vcCwgc28gcHJvZHVjZXJzIGNhbiBmb3J3YXJkIGl0IHRvXG4gKiBhbnkgaW4tZmxpZ2h0IHdvcmsgKGBmZXRjaGAsIFNESyBjYWxscywgZXRjLikgYW5kIGhhdmUgYSBzaW5nbGVcbiAqIGNhbmNlbGxhdGlvbiBzb3VyY2UgdGVhciBkb3duIGJvdGggdGhlIHJlcXVlc3QgYW5kIHRoZSBsb29wLlxuICpcbiAqIGBhdHRyaWJ1dGVzYCBpcyBhIG11dGFibGUgc2NyYXRjaHBhZCBzaGFyZWQgYWNyb3NzIGV2ZXJ5XG4gKiBpdGVyYXRpb24gb2YgYSBzaW5nbGUgYHBvbGxgIHJ1bi4gVGhlIHNhbWUgb2JqZWN0IHJlZmVyZW5jZSBpc1xuICogcGFzc2VkIGVhY2ggY2FsbCBzbyB3cml0ZXMgZnJvbSBvbmUgaXRlcmF0aW9uIGFyZSB2aXNpYmxlIHRvIHRoZVxuICogbmV4dCAtIHVzZWZ1bCBmb3Igc3Rhc2hpbmcgcGVyLWxvb3Agc3RhdGUgKHJldHJ5IGNvdW50ZXJzLCBzdGFydFxuICogdGltZXN0YW1wcywgYW55dGhpbmcgeW91J2Qgb3RoZXJ3aXNlIGNsb3NlIG92ZXIgdmlhIGEgbGV0KS5cbiAqIEdlbmVyaWMgYEFgIGxldHMgY2FsbGVycyB0eXBlIHRoZSBiYWc7IGRlZmF1bHRzIHRvXG4gKiBgUmVjb3JkPHN0cmluZywgdW5rbm93bj5gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvbGxDb250ZXh0PFQsIEEgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ge1xuICAvKiogWmVyby1iYXNlZCBpdGVyYXRpb24gaW5kZXggKGAwYCBvbiB0aGUgZmlyc3QgY2FsbCkuICovXG4gIGF0dGVtcHQ6IG51bWJlcjtcbiAgLyoqIFZhbHVlIHlpZWxkZWQgb24gdGhlIHByaW9yIGl0ZXJhdGlvbjsgYHVuZGVmaW5lZGAgb24gdGhlIGZpcnN0LiAqL1xuICBwcmV2aW91czogVCB8IHVuZGVmaW5lZDtcbiAgLyoqIENhbmNlbGxhdGlvbiBoYW5kbGUuIEFsd2F5cyBkZWZpbmVkOyBmb3J3YXJkIHRvIGluLWZsaWdodCB3b3JrLiAqL1xuICBzaWduYWw6IEFib3J0U2lnbmFsO1xuICAvKiogUGVyLXJ1biBtdXRhYmxlIHNjcmF0Y2hwYWQgc2hhcmVkIGFjcm9zcyBpdGVyYXRpb25zLiAqL1xuICBhdHRyaWJ1dGVzOiBBO1xufVxuXG4vKiogT25lIHN0ZXAgb2YgYSB7QGxpbmsgcG9sbH0gbG9vcC4gU2VlIHtAbGluayBQb2xsQ29udGV4dH0uICovXG5leHBvcnQgdHlwZSBQb2xsUHJvZHVjZXI8VCwgQSA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+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;