@atproto/common-web 0.5.1 → 0.5.3
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/CHANGELOG.md +26 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +5 -3
- package/dist/util.js.map +1 -1
- package/package.json +18 -13
- package/jest.config.cjs +0 -21
- package/src/arrays.ts +0 -23
- package/src/async.ts +0 -214
- package/src/check.ts +0 -31
- package/src/did-doc.ts +0 -202
- package/src/index.ts +0 -13
- package/src/ipld.ts +0 -48
- package/src/retry.ts +0 -58
- package/src/strings.ts +0 -49
- package/src/tid.ts +0 -110
- package/src/times.ts +0 -15
- package/src/types.ts +0 -64
- package/src/util.ts +0 -180
- package/tests/check.test.ts +0 -89
- package/tests/retry.test.ts +0 -93
- package/tests/tid.test.ts +0 -142
- package/tests/util.test.ts +0 -107
- package/tsconfig.build.json +0 -8
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.json +0 -7
- package/tsconfig.tests.json +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @atproto/common-web
|
|
2
2
|
|
|
3
|
+
## 0.5.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#5099](https://github.com/bluesky-social/atproto/pull/5099) [`b43ec31`](https://github.com/bluesky-social/atproto/commit/b43ec31f247f4461725b01226885f88bd430ca07) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Update TypeScript build to rely on references to composite internal projects
|
|
8
|
+
|
|
9
|
+
- [#5099](https://github.com/bluesky-social/atproto/pull/5099) [`b43ec31`](https://github.com/bluesky-social/atproto/commit/b43ec31f247f4461725b01226885f88bd430ca07) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Bundle only necessary files in the NPM tarball, including the `CHANGELOG.md` and `README.md` files (if present).
|
|
10
|
+
|
|
11
|
+
- [#5099](https://github.com/bluesky-social/atproto/pull/5099) [`b43ec31`](https://github.com/bluesky-social/atproto/commit/b43ec31f247f4461725b01226885f88bd430ca07) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Build with `noImplicitAny` enabled
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`28a0b58`](https://github.com/bluesky-social/atproto/commit/28a0b588147863eaef948cd2bb8fc0f19d08cda9), [`b43ec31`](https://github.com/bluesky-social/atproto/commit/b43ec31f247f4461725b01226885f88bd430ca07), [`b43ec31`](https://github.com/bluesky-social/atproto/commit/b43ec31f247f4461725b01226885f88bd430ca07), [`b43ec31`](https://github.com/bluesky-social/atproto/commit/b43ec31f247f4461725b01226885f88bd430ca07)]:
|
|
14
|
+
- @atproto/syntax@0.6.4
|
|
15
|
+
- @atproto/lex-data@0.1.4
|
|
16
|
+
- @atproto/lex-json@0.1.3
|
|
17
|
+
|
|
18
|
+
## 0.5.2
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- [#5151](https://github.com/bluesky-social/atproto/pull/5151) [`a51c45d`](https://github.com/bluesky-social/atproto/commit/a51c45d38f6bd7b8765f640e564cf921d52162e7) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Update dependencies
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [[`a51c45d`](https://github.com/bluesky-social/atproto/commit/a51c45d38f6bd7b8765f640e564cf921d52162e7)]:
|
|
25
|
+
- @atproto/lex-data@0.1.3
|
|
26
|
+
- @atproto/lex-json@0.1.2
|
|
27
|
+
- @atproto/syntax@0.6.3
|
|
28
|
+
|
|
3
29
|
## 0.5.1
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,GAAI,CAAC,OAC1B,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC,KACjC,MAAM,CAAC,MAAM,EAAE,CAAC,CAOlB,CAAA;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,OAAO,EAAE,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,KAAK,GAAG,cAAc,CAWxB;AASD;;;GAGG;AACH,wBAAgB,IAAI,CAClB,CAAC,SAAS,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,CAAC,SAAS,MAAM,WAAW,CAAC,CAAC,CAAC,EAE9B,MAAM,EAAE,CAAC,EACT,YAAY,EAAE,SAAS,CAAC,EAAE,GACzB,CAAC,SAAS,SAAS,GAAG,SAAS,GAAG,CAAC,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAoBvE,eAAO,MAAM,MAAM,UAAW,MAAM,WAEnC,CAAA;AAED,eAAO,MAAM,IAAI,OAAQ,MAAM,qBAE9B,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,YAAY,OAAQ,MAAM,KAAG,YAUzC,CAAA;AAED,eAAO,MAAM,kBAAkB,SAAU,UAAU,EAAE,KAAG,UAWvD,CAAA;AAED,eAAO,MAAM,cAAc,WACjB,aAAa,CAAC,UAAU,CAAC,KAChC,OAAO,CAAC,UAAU,CAMpB,CAAA;AAID,eAAO,MAAM,SAAS,MAAO,MAAM,KAAG,MAQrC,CAAA;AAED,eAAO,MAAM,SAAS,MAAO,MAAM,KAAG,MAMrC,CAAA;AAED,eAAO,MAAM,WAAW,GAAU,CAAC,OAC5B,CAAC,EAAE,MACJ,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,iBAI/B,CAAA;AAED,eAAO,MAAM,gBAAgB,QACtB,OAAO,KACX,GAAG,IAAI,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,GAAI,CAAC,OAC1B,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC,KACjC,MAAM,CAAC,MAAM,EAAE,CAAC,CAOlB,CAAA;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,OAAO,EAAE,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,KAAK,GAAG,cAAc,CAWxB;AASD;;;GAGG;AACH,wBAAgB,IAAI,CAClB,CAAC,SAAS,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,CAAC,SAAS,MAAM,WAAW,CAAC,CAAC,CAAC,EAE9B,MAAM,EAAE,CAAC,EACT,YAAY,EAAE,SAAS,CAAC,EAAE,GACzB,CAAC,SAAS,SAAS,GAAG,SAAS,GAAG,CAAC,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAoBvE,eAAO,MAAM,MAAM,UAAW,MAAM,WAEnC,CAAA;AAED,eAAO,MAAM,IAAI,OAAQ,MAAM,qBAE9B,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,YAAY,OAAQ,MAAM,KAAG,YAUzC,CAAA;AAED,eAAO,MAAM,kBAAkB,SAAU,UAAU,EAAE,KAAG,UAWvD,CAAA;AAED,eAAO,MAAM,cAAc,WACjB,aAAa,CAAC,UAAU,CAAC,KAChC,OAAO,CAAC,UAAU,CAMpB,CAAA;AAID,eAAO,MAAM,SAAS,MAAO,MAAM,KAAG,MAQrC,CAAA;AAED,eAAO,MAAM,SAAS,MAAO,MAAM,KAAG,MAMrC,CAAA;AAED,eAAO,MAAM,WAAW,GAAU,CAAC,OAC5B,CAAC,EAAE,MACJ,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,iBAI/B,CAAA;AAED,eAAO,MAAM,gBAAgB,QACtB,OAAO,KACX,GAAG,IAAI,MAAM,CAAC,cAIhB,CAAA;AAED,eAAO,MAAM,SAAS,QAAS,OAAO,OAAO,MAAM,KAAG,OAErD,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,CAAC,OAAO,CAAC,EAAE,aAAa,MAAM,KAAG,CAAC,EAAE,EAS9D,CAAA;AAED,eAAO,MAAM,KAAK,QAAS,MAAM,KAAG,MAAM,EAMzC,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,MAAM,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAG,CAAC,EAEjE,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAC7B,MAAM,GAAG,SAAS,YACf,CAAC,KACV,MAAM,GAAG,CAGX,CAAA"}
|
package/dist/util.js
CHANGED
|
@@ -51,7 +51,7 @@ export const bailableWait = (ms) => {
|
|
|
51
51
|
res();
|
|
52
52
|
};
|
|
53
53
|
});
|
|
54
|
-
return { bail, wait: () => waitPromise };
|
|
54
|
+
return { bail: bail, wait: () => waitPromise };
|
|
55
55
|
};
|
|
56
56
|
export const flattenUint8Arrays = (arrs) => {
|
|
57
57
|
const length = arrs.reduce((acc, cur) => {
|
|
@@ -94,10 +94,12 @@ export const asyncFilter = async (arr, fn) => {
|
|
|
94
94
|
return arr.filter((_, i) => results[i]);
|
|
95
95
|
};
|
|
96
96
|
export const isErrnoException = (err) => {
|
|
97
|
-
|
|
97
|
+
// @TODO This implementation does not actually safely checks if the error is
|
|
98
|
+
// an ErrnoException.
|
|
99
|
+
return !!err?.code;
|
|
98
100
|
};
|
|
99
101
|
export const errHasMsg = (err, msg) => {
|
|
100
|
-
return
|
|
102
|
+
return typeof err === 'object' && err != null && err.message === msg;
|
|
101
103
|
};
|
|
102
104
|
export const chunkArray = (arr, chunkSize) => {
|
|
103
105
|
return arr.reduce((acc, cur, i) => {
|
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,GAAkC,EACf,EAAE;IACrB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,GAAG,CAAC,CAAC,CAAC,CAAA;QACf,CAAC;IACH,CAAC;IACD,OAAO,GAAwB,CAAA;AACjC,CAAC,CAAA;AAED,MAAM,UAAU,eAAe,CAC7B,MAAiB,EACjB,OAAgB;IAEhB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,CAAC,CAAC,YAAY,KAAK;YAC/B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACX,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAC3E,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,cAAc,CACvB,MAAM,EACN,OAAO,IAAI,oBAAoB,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACvE,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,MAAe;IACrC,IAAI,MAAM,YAAY,KAAK,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAA;AACvB,CAAC;AAaD,MAAM,UAAU,IAAI,CAClB,GAA+C,EAC/C,YAA+B;IAE/B,WAAW;IAEX,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,CAAA;IAEpB,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["export const noUndefinedVals = <T>(\n obj: Record<string, T | undefined>,\n): Record<string, T> => {\n for (const k of Object.keys(obj)) {\n if (obj[k] === undefined) {\n delete obj[k]\n }\n }\n return obj as Record<string, T>\n}\n\nexport function aggregateErrors(\n errors: unknown[],\n message?: string,\n): Error | AggregateError {\n if (errors.length === 1) {\n return errors[0] instanceof Error\n ? errors[0]\n : new Error(message ?? stringifyError(errors[0]), { cause: errors[0] })\n } else {\n return new AggregateError(\n errors,\n message ?? `Multiple errors: ${errors.map(stringifyError).join('\\n')}`,\n )\n }\n}\n\nfunction stringifyError(reason: unknown): string {\n if (reason instanceof Error) {\n return reason.message\n }\n return String(reason)\n}\n\n/**\n * Returns a shallow copy of the object without the specified keys. If the input\n * is nullish, it returns the input.\n */\nexport function omit<\n T extends undefined | null | Record<string, unknown>,\n K extends keyof NonNullable<T>,\n>(\n object: T,\n rejectedKeys: readonly K[],\n): T extends undefined ? undefined : T extends null ? null : Omit<T, K>\nexport function omit(\n src: undefined | null | Record<string, unknown>,\n rejectedKeys: readonly string[],\n): undefined | null | Record<string, unknown> {\n // Hot path\n\n if (!src) return src\n\n const dst: Record<string, unknown> = {}\n const srcKeys = Object.keys(src)\n for (let i = 0; i < srcKeys.length; i++) {\n const key = srcKeys[i]\n if (!rejectedKeys.includes(key)) {\n dst[key] = src[key]\n }\n }\n return dst\n}\n\nexport const jitter = (maxMs: number) => {\n return Math.round((Math.random() - 0.5) * maxMs * 2)\n}\n\nexport const wait = (ms: number) => {\n return new Promise((res) => setTimeout(res, ms))\n}\n\nexport type BailableWait = {\n bail: () => void\n wait: () => Promise<void>\n}\n\nexport const bailableWait = (ms: number): BailableWait => {\n let bail: () => void\n const waitPromise = new Promise<void>((res) => {\n const timeout = setTimeout(res, ms)\n bail = () => {\n clearTimeout(timeout)\n res()\n }\n })\n return { bail: bail!, wait: () => waitPromise }\n}\n\nexport const flattenUint8Arrays = (arrs: Uint8Array[]): Uint8Array => {\n const length = arrs.reduce((acc, cur) => {\n return acc + cur.length\n }, 0)\n const flattened = new Uint8Array(length)\n let offset = 0\n arrs.forEach((arr) => {\n flattened.set(arr, offset)\n offset += arr.length\n })\n return flattened\n}\n\nexport const streamToBuffer = async (\n stream: AsyncIterable<Uint8Array>,\n): Promise<Uint8Array> => {\n const arrays: Uint8Array[] = []\n for await (const chunk of stream) {\n arrays.push(chunk)\n }\n return flattenUint8Arrays(arrays)\n}\n\nconst S32_CHAR = '234567abcdefghijklmnopqrstuvwxyz'\n\nexport const s32encode = (i: number): string => {\n let s = ''\n while (i) {\n const c = i % 32\n i = Math.floor(i / 32)\n s = S32_CHAR.charAt(c) + s\n }\n return s\n}\n\nexport const s32decode = (s: string): number => {\n let i = 0\n for (const c of s) {\n i = i * 32 + S32_CHAR.indexOf(c)\n }\n return i\n}\n\nexport const asyncFilter = async <T>(\n arr: T[],\n fn: (t: T) => Promise<boolean>,\n) => {\n const results = await Promise.all(arr.map((t) => fn(t)))\n return arr.filter((_, i) => results[i])\n}\n\nexport const isErrnoException = (\n err: unknown,\n): err is NodeJS.ErrnoException => {\n // @TODO This implementation does not actually safely checks if the error is\n // an ErrnoException.\n return !!(err as any)?.code\n}\n\nexport const errHasMsg = (err: unknown, msg: string): boolean => {\n return typeof err === 'object' && err != null && (err as any).message === msg\n}\n\nexport const chunkArray = <T>(arr: T[], chunkSize: number): T[][] => {\n return arr.reduce((acc, cur, i) => {\n const chunkI = Math.floor(i / chunkSize)\n if (!acc[chunkI]) {\n acc[chunkI] = []\n }\n acc[chunkI].push(cur)\n return acc\n }, [] as T[][])\n}\n\nexport const range = (num: number): number[] => {\n const nums: number[] = []\n for (let i = 0; i < num; i++) {\n nums.push(i)\n }\n return nums\n}\n\nexport const dedupeStrs = <T extends string>(strs: Iterable<T>): T[] => {\n return [...new Set(strs)]\n}\n\nexport const parseIntWithFallback = <T>(\n value: string | undefined,\n fallback: T,\n): number | T => {\n const parsed = parseInt(value || '', 10)\n return isNaN(parsed) ? fallback : parsed\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/common-web",
|
|
3
|
-
"version": "0.5.
|
|
4
|
-
"engines": {
|
|
5
|
-
"node": ">=22"
|
|
6
|
-
},
|
|
3
|
+
"version": "0.5.3",
|
|
7
4
|
"license": "MIT",
|
|
8
5
|
"description": "Shared web-platform-friendly code for atproto libraries",
|
|
9
6
|
"keywords": [
|
|
@@ -15,15 +12,11 @@
|
|
|
15
12
|
"url": "https://github.com/bluesky-social/atproto",
|
|
16
13
|
"directory": "packages/common-web"
|
|
17
14
|
},
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
},
|
|
24
|
-
"devDependencies": {
|
|
25
|
-
"jest": "^30.0.0"
|
|
26
|
-
},
|
|
15
|
+
"files": [
|
|
16
|
+
"./dist",
|
|
17
|
+
"./README.md",
|
|
18
|
+
"./CHANGELOG.md"
|
|
19
|
+
],
|
|
27
20
|
"type": "module",
|
|
28
21
|
"exports": {
|
|
29
22
|
".": {
|
|
@@ -31,6 +24,18 @@
|
|
|
31
24
|
"default": "./dist/index.js"
|
|
32
25
|
}
|
|
33
26
|
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"zod": "^3.23.8",
|
|
32
|
+
"@atproto/lex-data": "^0.1.4",
|
|
33
|
+
"@atproto/lex-json": "^0.1.3",
|
|
34
|
+
"@atproto/syntax": "^0.6.4"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"jest": "^30.0.0"
|
|
38
|
+
},
|
|
34
39
|
"scripts": {
|
|
35
40
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
|
|
36
41
|
"build": "tsgo --build tsconfig.build.json"
|
package/jest.config.cjs
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/** @type {import('jest').Config} */
|
|
2
|
-
module.exports = {
|
|
3
|
-
displayName: 'Common Web',
|
|
4
|
-
transform: {
|
|
5
|
-
'^.+\\.(t|j)s$': [
|
|
6
|
-
'@swc/jest',
|
|
7
|
-
{
|
|
8
|
-
jsc: {
|
|
9
|
-
parser: { syntax: 'typescript', importAttributes: true },
|
|
10
|
-
experimental: { keepImportAttributes: true },
|
|
11
|
-
transform: {},
|
|
12
|
-
},
|
|
13
|
-
module: { type: 'es6' },
|
|
14
|
-
},
|
|
15
|
-
],
|
|
16
|
-
},
|
|
17
|
-
extensionsToTreatAsEsm: ['.ts'],
|
|
18
|
-
transformIgnorePatterns: [],
|
|
19
|
-
setupFiles: ['<rootDir>/../../test.setup.ts'],
|
|
20
|
-
moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] },
|
|
21
|
-
}
|
package/src/arrays.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export function keyBy<T, K extends keyof T>(
|
|
2
|
-
arr: readonly T[],
|
|
3
|
-
key: K,
|
|
4
|
-
): Map<T[K], T> {
|
|
5
|
-
return arr.reduce((acc, cur) => {
|
|
6
|
-
acc.set(cur[key], cur)
|
|
7
|
-
return acc
|
|
8
|
-
}, new Map<T[K], T>())
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const mapDefined = <T, S>(
|
|
12
|
-
arr: T[],
|
|
13
|
-
fn: (obj: T) => S | undefined,
|
|
14
|
-
): S[] => {
|
|
15
|
-
const output: S[] = []
|
|
16
|
-
for (const item of arr) {
|
|
17
|
-
const val = fn(item)
|
|
18
|
-
if (val !== undefined) {
|
|
19
|
-
output.push(val)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return output
|
|
23
|
-
}
|
package/src/async.ts
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import { aggregateErrors, bailableWait } from './util.js'
|
|
2
|
-
|
|
3
|
-
// reads values from a generator into a list
|
|
4
|
-
// breaks when isDone signals `true` AND `waitFor` completes OR when a max length is reached
|
|
5
|
-
// NOTE: does not signal generator to close. it *will* continue to produce values
|
|
6
|
-
export const readFromGenerator = async <T>(
|
|
7
|
-
gen: AsyncGenerator<T>,
|
|
8
|
-
isDone: (last?: T) => Promise<boolean> | boolean,
|
|
9
|
-
waitFor: Promise<unknown> = Promise.resolve(),
|
|
10
|
-
maxLength = Number.MAX_SAFE_INTEGER,
|
|
11
|
-
): Promise<T[]> => {
|
|
12
|
-
const evts: T[] = []
|
|
13
|
-
let bail: undefined | (() => void)
|
|
14
|
-
let hasBroke = false
|
|
15
|
-
const awaitDone = async () => {
|
|
16
|
-
if (await isDone(evts.at(-1))) {
|
|
17
|
-
return true
|
|
18
|
-
}
|
|
19
|
-
const bailable = bailableWait(20)
|
|
20
|
-
await bailable.wait()
|
|
21
|
-
bail = bailable.bail
|
|
22
|
-
if (hasBroke) return false
|
|
23
|
-
return await awaitDone()
|
|
24
|
-
}
|
|
25
|
-
const breakOn: Promise<void> = new Promise((resolve) => {
|
|
26
|
-
waitFor.then(() => {
|
|
27
|
-
awaitDone().then(() => resolve())
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
while (evts.length < maxLength) {
|
|
33
|
-
const maybeEvt = await Promise.race([gen.next(), breakOn])
|
|
34
|
-
if (!maybeEvt) break
|
|
35
|
-
const evt = maybeEvt as IteratorResult<T>
|
|
36
|
-
if (evt.done) break
|
|
37
|
-
evts.push(evt.value)
|
|
38
|
-
}
|
|
39
|
-
} finally {
|
|
40
|
-
hasBroke = true
|
|
41
|
-
if (bail) bail()
|
|
42
|
-
}
|
|
43
|
-
return evts
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export type Deferrable<T = void> = {
|
|
47
|
-
resolve: (value: T | PromiseLike<T>) => void
|
|
48
|
-
reject: (reason?: unknown) => void
|
|
49
|
-
complete: Promise<T>
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function createDeferrable<T = void>(): Deferrable<T> {
|
|
53
|
-
let res: (value: T | PromiseLike<T>) => void
|
|
54
|
-
let rej: (reason?: unknown) => void
|
|
55
|
-
const promise = new Promise<T>((resolve, reject) => {
|
|
56
|
-
res = resolve
|
|
57
|
-
rej = reject
|
|
58
|
-
})
|
|
59
|
-
return { resolve: res!, reject: rej!, complete: promise }
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export const createDeferrables = (count: number): Deferrable[] => {
|
|
63
|
-
const list: Deferrable[] = []
|
|
64
|
-
for (let i = 0; i < count; i++) {
|
|
65
|
-
list.push(createDeferrable())
|
|
66
|
-
}
|
|
67
|
-
return list
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export const allComplete = async (deferrables: Deferrable[]): Promise<void> => {
|
|
71
|
-
await Promise.all(deferrables.map((d) => d.complete))
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export class AsyncBuffer<T> {
|
|
75
|
-
private buffer: T[] = []
|
|
76
|
-
private promise: Promise<void>
|
|
77
|
-
private resolve: () => void
|
|
78
|
-
private closed = false
|
|
79
|
-
private toThrow: unknown | undefined
|
|
80
|
-
|
|
81
|
-
constructor(public maxSize?: number) {
|
|
82
|
-
// Initializing to satisfy types/build, immediately reset by resetPromise()
|
|
83
|
-
this.promise = Promise.resolve()
|
|
84
|
-
this.resolve = () => null
|
|
85
|
-
this.resetPromise()
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
get curr(): T[] {
|
|
89
|
-
return this.buffer
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
get size(): number {
|
|
93
|
-
return this.buffer.length
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
get isClosed(): boolean {
|
|
97
|
-
return this.closed
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
resetPromise() {
|
|
101
|
-
this.promise = new Promise<void>((r) => (this.resolve = r))
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
push(item: T) {
|
|
105
|
-
this.buffer.push(item)
|
|
106
|
-
this.resolve()
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
pushMany(items: T[]) {
|
|
110
|
-
items.forEach((i) => this.buffer.push(i))
|
|
111
|
-
this.resolve()
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async *events(): AsyncGenerator<T> {
|
|
115
|
-
while (true) {
|
|
116
|
-
if (this.closed && this.buffer.length === 0) {
|
|
117
|
-
if (this.toThrow) {
|
|
118
|
-
throw this.toThrow
|
|
119
|
-
} else {
|
|
120
|
-
return
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
await this.promise
|
|
124
|
-
if (this.toThrow) {
|
|
125
|
-
throw this.toThrow
|
|
126
|
-
}
|
|
127
|
-
if (this.maxSize && this.size > this.maxSize) {
|
|
128
|
-
throw new AsyncBufferFullError(this.maxSize)
|
|
129
|
-
}
|
|
130
|
-
const [first, ...rest] = this.buffer
|
|
131
|
-
if (first) {
|
|
132
|
-
this.buffer = rest
|
|
133
|
-
yield first
|
|
134
|
-
} else {
|
|
135
|
-
this.resetPromise()
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
throw(err: unknown) {
|
|
141
|
-
this.toThrow = err
|
|
142
|
-
this.closed = true
|
|
143
|
-
this.resolve()
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
close() {
|
|
147
|
-
this.closed = true
|
|
148
|
-
this.resolve()
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export class AsyncBufferFullError extends Error {
|
|
153
|
-
constructor(maxSize: number) {
|
|
154
|
-
super(`ReachedMaxBufferSize: ${maxSize}`)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Utility function that behaves like {@link Promise.allSettled} but returns the
|
|
160
|
-
* same result as {@link Promise.all} in case every promise is fulfilled, and
|
|
161
|
-
* throws an {@link AggregateError} if there are more than one errors.
|
|
162
|
-
*/
|
|
163
|
-
export function allFulfilled<T extends readonly unknown[] | []>(
|
|
164
|
-
promises: T,
|
|
165
|
-
): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>
|
|
166
|
-
export function allFulfilled<T>(
|
|
167
|
-
promises: Iterable<T | PromiseLike<T>>,
|
|
168
|
-
): Promise<Awaited<T>[]>
|
|
169
|
-
export function allFulfilled(
|
|
170
|
-
promises: Iterable<Promise<unknown>>,
|
|
171
|
-
): Promise<unknown[]> {
|
|
172
|
-
return Promise.allSettled(promises).then(handleAllSettledErrors)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export function handleAllSettledErrors<
|
|
176
|
-
T extends readonly PromiseSettledResult<unknown>[] | [],
|
|
177
|
-
>(
|
|
178
|
-
results: T,
|
|
179
|
-
): {
|
|
180
|
-
-readonly [P in keyof T]: T[P] extends PromiseSettledResult<infer U>
|
|
181
|
-
? U
|
|
182
|
-
: never
|
|
183
|
-
}
|
|
184
|
-
export function handleAllSettledErrors<T>(
|
|
185
|
-
results: PromiseSettledResult<T>[],
|
|
186
|
-
): T[]
|
|
187
|
-
export function handleAllSettledErrors(
|
|
188
|
-
results: PromiseSettledResult<unknown>[],
|
|
189
|
-
): unknown[] {
|
|
190
|
-
if (results.every(isFulfilledResult)) return results.map(extractValue)
|
|
191
|
-
|
|
192
|
-
const errors = results.filter(isRejectedResult).map(extractReason)
|
|
193
|
-
throw aggregateErrors(errors)
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export function isRejectedResult(
|
|
197
|
-
result: PromiseSettledResult<unknown>,
|
|
198
|
-
): result is PromiseRejectedResult {
|
|
199
|
-
return result.status === 'rejected'
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function extractReason(result: PromiseRejectedResult): unknown {
|
|
203
|
-
return result.reason
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export function isFulfilledResult<T>(
|
|
207
|
-
result: PromiseSettledResult<T>,
|
|
208
|
-
): result is PromiseFulfilledResult<T> {
|
|
209
|
-
return result.status === 'fulfilled'
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function extractValue<T>(result: PromiseFulfilledResult<T>): T {
|
|
213
|
-
return result.value
|
|
214
|
-
}
|
package/src/check.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// Explicitly not using "zod" types here to avoid mismatching types due to
|
|
2
|
-
// version differences.
|
|
3
|
-
|
|
4
|
-
export interface Checkable<T> {
|
|
5
|
-
parse: (obj: unknown) => T
|
|
6
|
-
safeParse: (
|
|
7
|
-
obj: unknown,
|
|
8
|
-
) => { success: true; data: T } | { success: false; error: Error }
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface Def<T> {
|
|
12
|
-
name: string
|
|
13
|
-
schema: Checkable<T>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const is = <T>(obj: unknown, def: Checkable<T>): obj is T => {
|
|
17
|
-
return def.safeParse(obj).success
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const create =
|
|
21
|
-
<T>(def: Checkable<T>) =>
|
|
22
|
-
(v: unknown): v is T =>
|
|
23
|
-
def.safeParse(v).success
|
|
24
|
-
|
|
25
|
-
export const assure = <T>(def: Checkable<T>, obj: unknown): T => {
|
|
26
|
-
return def.parse(obj)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const isObject = (obj: unknown): obj is Record<string, unknown> => {
|
|
30
|
-
return typeof obj === 'object' && obj !== null
|
|
31
|
-
}
|
package/src/did-doc.ts
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
|
|
3
|
-
// Parsing atproto data
|
|
4
|
-
// --------
|
|
5
|
-
|
|
6
|
-
export const isValidDidDoc = (doc: unknown): doc is DidDocument => {
|
|
7
|
-
return didDocument.safeParse(doc).success
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const getDid = (doc: DidDocument): string => {
|
|
11
|
-
const id = doc.id
|
|
12
|
-
if (typeof id !== 'string') {
|
|
13
|
-
throw new Error('No `id` on document')
|
|
14
|
-
}
|
|
15
|
-
return id
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const getHandle = (doc: DidDocument): string | undefined => {
|
|
19
|
-
const aka = doc.alsoKnownAs
|
|
20
|
-
if (aka) {
|
|
21
|
-
for (let i = 0; i < aka.length; i++) {
|
|
22
|
-
const alias = aka[i]
|
|
23
|
-
if (alias.startsWith('at://')) {
|
|
24
|
-
// strip off "at://" prefix
|
|
25
|
-
return alias.slice(5)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return undefined
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// @NOTE we parse to type/publicKeyMultibase to avoid the dependency on @atproto/crypto
|
|
33
|
-
export const getSigningKey = (
|
|
34
|
-
doc: DidDocument,
|
|
35
|
-
): { type: string; publicKeyMultibase: string } | undefined => {
|
|
36
|
-
return getVerificationMaterial(doc, 'atproto')
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export const getVerificationMaterial = (
|
|
40
|
-
doc: DidDocument,
|
|
41
|
-
keyId: string,
|
|
42
|
-
): { type: string; publicKeyMultibase: string } | undefined => {
|
|
43
|
-
// /!\ Hot path
|
|
44
|
-
|
|
45
|
-
const key = findItemById(doc, 'verificationMethod', `#${keyId}`)
|
|
46
|
-
if (!key) {
|
|
47
|
-
return undefined
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!key.publicKeyMultibase) {
|
|
51
|
-
return undefined
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
type: key.type,
|
|
56
|
-
publicKeyMultibase: key.publicKeyMultibase,
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export const getSigningDidKey = (doc: DidDocument): string | undefined => {
|
|
61
|
-
const parsed = getSigningKey(doc)
|
|
62
|
-
if (!parsed) return
|
|
63
|
-
return `did:key:${parsed.publicKeyMultibase}`
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export const getPdsEndpoint = (doc: DidDocument): string | undefined => {
|
|
67
|
-
return getServiceEndpoint(doc, {
|
|
68
|
-
id: '#atproto_pds',
|
|
69
|
-
type: 'AtprotoPersonalDataServer',
|
|
70
|
-
})
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export const getFeedGenEndpoint = (doc: DidDocument): string | undefined => {
|
|
74
|
-
return getServiceEndpoint(doc, {
|
|
75
|
-
id: '#bsky_fg',
|
|
76
|
-
type: 'BskyFeedGenerator',
|
|
77
|
-
})
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export const getNotifEndpoint = (doc: DidDocument): string | undefined => {
|
|
81
|
-
return getServiceEndpoint(doc, {
|
|
82
|
-
id: '#bsky_notif',
|
|
83
|
-
type: 'BskyNotificationService',
|
|
84
|
-
})
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export const getServiceEndpoint = (
|
|
88
|
-
doc: DidDocument,
|
|
89
|
-
opts: { id: string; type?: string },
|
|
90
|
-
) => {
|
|
91
|
-
// /!\ Hot path
|
|
92
|
-
|
|
93
|
-
const service = findItemById(doc, 'service', opts.id)
|
|
94
|
-
if (!service) {
|
|
95
|
-
return undefined
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (opts.type && service.type !== opts.type) {
|
|
99
|
-
return undefined
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (typeof service.serviceEndpoint !== 'string') {
|
|
103
|
-
return undefined
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return validateUrl(service.serviceEndpoint)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function findItemById<
|
|
110
|
-
D extends DidDocument,
|
|
111
|
-
T extends 'verificationMethod' | 'service',
|
|
112
|
-
>(doc: D, type: T, id: string): NonNullable<D[T]>[number] | undefined
|
|
113
|
-
function findItemById(
|
|
114
|
-
doc: DidDocument,
|
|
115
|
-
type: 'verificationMethod' | 'service',
|
|
116
|
-
id: string,
|
|
117
|
-
) {
|
|
118
|
-
// /!\ Hot path
|
|
119
|
-
|
|
120
|
-
const items = doc[type]
|
|
121
|
-
if (items) {
|
|
122
|
-
for (let i = 0; i < items.length; i++) {
|
|
123
|
-
const item = items[i]
|
|
124
|
-
const itemId = item.id
|
|
125
|
-
|
|
126
|
-
if (
|
|
127
|
-
itemId[0] === '#'
|
|
128
|
-
? itemId === id
|
|
129
|
-
: // Optimized version of: itemId === `${doc.id}${id}`
|
|
130
|
-
itemId.length === doc.id.length + id.length &&
|
|
131
|
-
itemId[doc.id.length] === '#' &&
|
|
132
|
-
itemId.endsWith(id) &&
|
|
133
|
-
itemId.startsWith(doc.id) // <== We could probably skip this check
|
|
134
|
-
) {
|
|
135
|
-
return item
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return undefined
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Check protocol and hostname to prevent potential SSRF
|
|
143
|
-
const validateUrl = (urlStr: string): string | undefined => {
|
|
144
|
-
if (!urlStr.startsWith('http://') && !urlStr.startsWith('https://')) {
|
|
145
|
-
return undefined
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (!canParseUrl(urlStr)) {
|
|
149
|
-
return undefined
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return urlStr
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const canParseUrl =
|
|
156
|
-
URL.canParse ??
|
|
157
|
-
// URL.canParse is not available in Node.js < 18.17.0
|
|
158
|
-
((urlStr: string): boolean => {
|
|
159
|
-
try {
|
|
160
|
-
new URL(urlStr)
|
|
161
|
-
return true
|
|
162
|
-
} catch {
|
|
163
|
-
return false
|
|
164
|
-
}
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
// Types
|
|
168
|
-
// --------
|
|
169
|
-
|
|
170
|
-
const verificationMethod = z.object({
|
|
171
|
-
id: z.string(),
|
|
172
|
-
type: z.string(),
|
|
173
|
-
controller: z.string(),
|
|
174
|
-
publicKeyJwk: z.record(z.string(), z.unknown()).optional(),
|
|
175
|
-
publicKeyMultibase: z.string().optional(),
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
const service = z.object({
|
|
179
|
-
id: z.string(),
|
|
180
|
-
type: z.string(),
|
|
181
|
-
serviceEndpoint: z.union([z.string(), z.record(z.unknown())]),
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* @deprecated Use `DidDocument` from `@atproto/did` instead as it applies
|
|
186
|
-
* stricter (and more spec-compliant) validation.
|
|
187
|
-
*/
|
|
188
|
-
export const didDocument = z.object({
|
|
189
|
-
'@context': z
|
|
190
|
-
.union([
|
|
191
|
-
z.literal('https://www.w3.org/ns/did/v1'),
|
|
192
|
-
z.array(z.string().url()),
|
|
193
|
-
])
|
|
194
|
-
.optional(),
|
|
195
|
-
id: z.string(),
|
|
196
|
-
alsoKnownAs: z.array(z.string()).optional(),
|
|
197
|
-
verificationMethod: z.array(verificationMethod).optional(),
|
|
198
|
-
authentication: z.array(z.union([z.string(), verificationMethod])).optional(),
|
|
199
|
-
service: z.array(service).optional(),
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
export type DidDocument = z.infer<typeof didDocument>
|
package/src/index.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export * as check from './check.js'
|
|
2
|
-
export * as util from './util.js'
|
|
3
|
-
|
|
4
|
-
export * from './arrays.js'
|
|
5
|
-
export * from './async.js'
|
|
6
|
-
export * from './util.js'
|
|
7
|
-
export * from './tid.js'
|
|
8
|
-
export * from './ipld.js'
|
|
9
|
-
export * from './retry.js'
|
|
10
|
-
export * from './types.js'
|
|
11
|
-
export * from './times.js'
|
|
12
|
-
export * from './strings.js'
|
|
13
|
-
export * from './did-doc.js'
|