@atproto/common-web 0.5.2 → 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 CHANGED
@@ -1,5 +1,20 @@
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
+
3
18
  ## 0.5.2
4
19
 
5
20
  ### Patch Changes
@@ -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,cAEhB,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"}
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
- return !!err && err['code'];
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 !!err && typeof err === 'object' && err['message'] === msg;
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":"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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 = {}\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\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, 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 return !!err && err['code']\n}\n\nexport const errHasMsg = (err: unknown, msg: string): boolean => {\n return !!err && typeof err === 'object' && err['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"]}
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.2",
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
- "dependencies": {
19
- "zod": "^3.23.8",
20
- "@atproto/lex-json": "^0.1.2",
21
- "@atproto/syntax": "^0.6.3",
22
- "@atproto/lex-data": "^0.1.3"
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'