@palantir/pack.core 0.0.1-beta.1

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.
Files changed (48) hide show
  1. package/.turbo/turbo-lint.log +4 -0
  2. package/.turbo/turbo-transpileBrowser.log +5 -0
  3. package/.turbo/turbo-transpileCjs.log +5 -0
  4. package/.turbo/turbo-transpileEsm.log +5 -0
  5. package/.turbo/turbo-transpileTypes.log +5 -0
  6. package/.turbo/turbo-typecheck.log +4 -0
  7. package/LICENSE.txt +13 -0
  8. package/README.md +7 -0
  9. package/build/browser/index.js +50 -0
  10. package/build/browser/index.js.map +1 -0
  11. package/build/cjs/index.cjs +56 -0
  12. package/build/cjs/index.cjs.map +1 -0
  13. package/build/cjs/index.d.cts +207 -0
  14. package/build/esm/index.js +50 -0
  15. package/build/esm/index.js.map +1 -0
  16. package/build/types/index.d.ts +10 -0
  17. package/build/types/index.d.ts.map +1 -0
  18. package/build/types/types/AppConfig.d.ts +68 -0
  19. package/build/types/types/AppConfig.d.ts.map +1 -0
  20. package/build/types/types/Branded.d.ts +29 -0
  21. package/build/types/types/Branded.d.ts.map +1 -0
  22. package/build/types/types/ModuleKey.d.ts +53 -0
  23. package/build/types/types/ModuleKey.d.ts.map +1 -0
  24. package/build/types/types/PackApp.d.ts +49 -0
  25. package/build/types/types/PackApp.d.ts.map +1 -0
  26. package/build/types/types/TokenProvider.d.ts +1 -0
  27. package/build/types/types/TokenProvider.d.ts.map +1 -0
  28. package/build/types/types/Unsubscribe.d.ts +1 -0
  29. package/build/types/types/Unsubscribe.d.ts.map +1 -0
  30. package/build/types/utils/assertNever.d.ts +1 -0
  31. package/build/types/utils/assertNever.d.ts.map +1 -0
  32. package/build/types/utils/generateId.d.ts +1 -0
  33. package/build/types/utils/generateId.d.ts.map +1 -0
  34. package/build/types/utils/justOnce.d.ts +10 -0
  35. package/build/types/utils/justOnce.d.ts.map +1 -0
  36. package/package.json +67 -0
  37. package/src/index.ts +26 -0
  38. package/src/types/AppConfig.ts +97 -0
  39. package/src/types/Branded.ts +44 -0
  40. package/src/types/ModuleKey.ts +67 -0
  41. package/src/types/PackApp.ts +82 -0
  42. package/src/types/TokenProvider.ts +17 -0
  43. package/src/types/Unsubscribe.ts +17 -0
  44. package/src/utils/assertNever.ts +19 -0
  45. package/src/utils/generateId.ts +28 -0
  46. package/src/utils/justOnce.ts +33 -0
  47. package/tsconfig.json +21 -0
  48. package/vitest.config.mjs +26 -0
@@ -0,0 +1,49 @@
1
+ import type { AppConfig } from "./AppConfig.js";
2
+ import type { ModuleKey } from "./ModuleKey.js";
3
+ /**
4
+ * PackApp provides access to various pack subsystems.
5
+ *
6
+ * Specific modules are available after configuration and through declarations mixed in by import.
7
+ * Eg for state system, if you import @palantir/pack.state.core you will have access to `app.state` accessor.
8
+ * Similarly, auth is added automatically by initPackApp.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { DocumentRef } from '@palantir/pack.state.core';
13
+ * import { DocSchema } from '@my-app/schema';
14
+ *
15
+ * const app = initPackApp({
16
+ * tokenProvider: () => 'your-token',
17
+ * moduleConfigs: {
18
+ * ...createPackDocumentServiceConfig({appId: 'your-app-id', documentType: 'your-document-type'})
19
+ * },
20
+ * });
21
+ *
22
+ * const docRef = app.state.getDocument(docSchema, 'your-document-id');
23
+ * const doc = await docRef.getSnapshot(); // get pojo of your doc state.
24
+ * ```
25
+ */
26
+ export interface PackApp {
27
+ readonly config: AppConfig;
28
+ }
29
+ /**
30
+ * Module configuration - either a tuple of [ModuleKey, config] or just a ModuleKey (for modules with no config)
31
+ */
32
+ export type ModuleConfigTuple<T = unknown> = readonly [ModuleKey<T>, unknown];
33
+ export type ModuleConfig<T = unknown> = ModuleConfigTuple<T> | ModuleKey<T>;
34
+ /**
35
+ * Type guard to check if a ModuleConfig is a tuple configuration
36
+ */
37
+ export declare const isModuleConfigTuple: (config: ModuleConfig) => config is readonly [ModuleKey<unknown>, unknown];
38
+ export interface PackAppInternal {
39
+ readonly config: AppConfig;
40
+ /**
41
+ * Internal module accessor
42
+ */
43
+ getModule<
44
+ T,
45
+ TConfig = undefined
46
+ >(moduleKey: ModuleKey<T, TConfig>): T;
47
+ }
48
+ export declare function assertIsAppInternal(app: PackApp): asserts app is PackApp & PackAppInternal;
49
+ export declare function assertIsAppInternal(app: PackAppInternal): asserts app is PackAppInternal;
@@ -0,0 +1 @@
1
+ {"mappings":"AAiBA,cAAc,iBAAiB;AAC/B,cAAc,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;AAyB/B,iBAAiB,QAAQ;UACd,QAAQ;;;;;AAOnB,YAAY,kBAAkB,yBAAyB,UAAU;AACjE,YAAY,aAAa,eAAe,kBAAkB,KAAK,UAAU;;;;AAKzE,OAAO,cAAM,sBACX,QAAQ,iBACP,oBAAoB;AAIvB,iBAAiB,gBAAgB;UACtB,QAAQ;;;;CAMjB;EAAU;EAAG;GAAqB,WAAW,UAAU,GAAG,WAAW;;AAGvE,OAAO,iBAAS,oBAAoB,KAAK,kBAAkB,OAAO,UAAU;AAC5E,OAAO,iBAAS,oBACd,KAAK,0BACI,OAAO","names":[],"sources":["../../../src/types/PackApp.ts"],"version":3,"file":"PackApp.d.ts"}
@@ -0,0 +1 @@
1
+ export type TokenProvider = () => Promise<string>;
@@ -0,0 +1 @@
1
+ {"mappings":"AAgBA,YAAY,sBAAsB","names":[],"sources":["../../../src/types/TokenProvider.ts"],"version":3,"file":"TokenProvider.d.ts"}
@@ -0,0 +1 @@
1
+ export type Unsubscribe = () => void;
@@ -0,0 +1 @@
1
+ {"mappings":"AAgBA,YAAY","names":[],"sources":["../../../src/types/Unsubscribe.ts"],"version":3,"file":"Unsubscribe.d.ts"}
@@ -0,0 +1 @@
1
+ export declare function assertNever(_x: never): never;
@@ -0,0 +1 @@
1
+ {"mappings":"AAgBA,OAAO,iBAAS,YAAY","names":[],"sources":["../../../src/utils/assertNever.ts"],"version":3,"file":"assertNever.d.ts"}
@@ -0,0 +1 @@
1
+ export declare function generateId(bytes?: number): string;
@@ -0,0 +1 @@
1
+ {"mappings":"AAuBA,OAAO,iBAAS,WAAW","names":[],"sources":["../../../src/utils/generateId.ts"],"version":3,"file":"generateId.d.ts"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Used to call fn only once between app reloads.
3
+ * eg: Useful for logging warnings that should only be logged once.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * justOnce("unexpected-value", () => console.warn("There was an unexpected value returned", {value}));
8
+ * ```
9
+ */
10
+ export declare function justOnce(key: string, fn: () => void): void;
@@ -0,0 +1 @@
1
+ {"mappings":";;;;;;;;;AA2BA,OAAO,iBAAS,SAAS,aAAa","names":[],"sources":["../../../src/utils/justOnce.ts"],"version":3,"file":"justOnce.d.ts"}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@palantir/pack.core",
3
+ "version": "0.0.1-beta.1",
4
+ "description": "PACK Core functionality and utilities",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/palantir/pack.git"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "browser": "./build/browser/index.js",
13
+ "import": {
14
+ "types": "./build/types/index.d.ts",
15
+ "default": "./build/esm/index.js"
16
+ },
17
+ "require": "./build/cjs/index.js",
18
+ "default": "./build/browser/index.js"
19
+ },
20
+ "./*": {
21
+ "browser": "./build/browser/public/*.js",
22
+ "import": {
23
+ "types": "./build/types/public/*.d.ts",
24
+ "default": "./build/js/public/*.js"
25
+ },
26
+ "require": "./build/cjs/public/*.js",
27
+ "default": "./build/browser/public/*.js"
28
+ }
29
+ },
30
+ "dependencies": {
31
+ "@osdk/client": "~2.4.2",
32
+ "remeda": "^2.32.0"
33
+ },
34
+ "peerDependencies": {
35
+ "@osdk/api": "~2.4.2"
36
+ },
37
+ "devDependencies": {
38
+ "rimraf": "^6.0.1",
39
+ "tiny-invariant": "^1.3.3",
40
+ "tslib": "^2.8.1",
41
+ "typescript": "^5.9.2",
42
+ "@palantir/pack.monorepo.tsconfig": "~0.4.0-beta.1"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "keywords": [
48
+ "pack",
49
+ "core"
50
+ ],
51
+ "main": "./build/cjs/index.js",
52
+ "module": "./build/esm/index.js",
53
+ "types": "./build/cjs/index.d.ts",
54
+ "type": "module",
55
+ "scripts": {
56
+ "clean": "rimraf .turbo build dist lib test-output *.tgz tsconfig.tsbuildinfo",
57
+ "lint": "eslint ./src ; dprint check --config $(find-up dprint.json) --allow-no-files",
58
+ "lint:fix": "eslint ./src --fix ; dprint fmt --config $(find-up dprint.json) --allow-no-files",
59
+ "test": "vitest run --passWithNoTests -u",
60
+ "test:watch": "vitest --passWithNoTests",
61
+ "transpileBrowser": "monorepo-transpile -f esm -m bundle -t browser",
62
+ "transpileCjs": "monorepo-transpile -f cjs -m bundle -t node",
63
+ "transpileEsm": "monorepo-transpile -f esm -m bundle -t node",
64
+ "transpileTypes": "monorepo-transpile -f esm -m types -t node",
65
+ "typecheck": "tsc --noEmit --emitDeclarationOnly false"
66
+ }
67
+ }
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export type { AppConfig, AppOptions } from "./types/AppConfig.js";
18
+ export type { Branded, Flavored } from "./types/Branded.js";
19
+ export type { ModuleKey } from "./types/ModuleKey.js";
20
+ export { assertIsAppInternal, isModuleConfigTuple } from "./types/PackApp.js";
21
+ export type { ModuleConfig, ModuleConfigTuple, PackApp, PackAppInternal } from "./types/PackApp.js";
22
+ export type { TokenProvider } from "./types/TokenProvider.js";
23
+ export type { Unsubscribe } from "./types/Unsubscribe.js";
24
+ export { assertNever } from "./utils/assertNever.js";
25
+ export { generateId } from "./utils/generateId.js";
26
+ export { justOnce } from "./utils/justOnce.js";
@@ -0,0 +1,97 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import type { Logger } from "@osdk/api";
18
+ import type { Client } from "@osdk/client";
19
+ import type { ModuleConfigTuple } from "./PackApp.js";
20
+ import type { TokenProvider } from "./TokenProvider.js";
21
+
22
+ export interface AppConfig {
23
+ readonly app: {
24
+ readonly appId: string;
25
+ readonly appVersion?: string;
26
+ };
27
+
28
+ readonly isTestMode: boolean;
29
+
30
+ readonly logger: Logger;
31
+
32
+ readonly osdkClient: Client;
33
+
34
+ readonly remote: {
35
+ readonly packApiPath: string;
36
+ readonly packWsPath: string;
37
+ readonly baseUrl: string;
38
+ readonly fetchFn: typeof globalThis.fetch;
39
+ };
40
+ }
41
+
42
+ export interface AppOptions {
43
+ /**
44
+ * Override the authentication token provider from the OSDK client.
45
+ *
46
+ * @default Uses token provider from OSDK client
47
+ */
48
+ readonly auth?: TokenProvider;
49
+
50
+ /**
51
+ * The ID of your application.
52
+ * @default Uses values from page environment meta tags (pack-appId, pack-appVersion)
53
+ */
54
+ readonly app?: {
55
+ readonly appId: string;
56
+ readonly appVersion?: string;
57
+ };
58
+
59
+ /**
60
+ * Logger configuration.
61
+ * @see {@link @osdk/client/internal.BrowserLogger} for a richer console logger.
62
+ * @default Log warnings & errors only.
63
+ */
64
+ readonly logger?: Logger;
65
+ readonly logLevel?: "debug" | "error" | "info" | "warn";
66
+
67
+ /**
68
+ * Internal testing overrides.
69
+ */
70
+ readonly moduleOverrides?: readonly ModuleConfigTuple[];
71
+
72
+ readonly remote?: {
73
+ /**
74
+ * @default "/pack/api"
75
+ */
76
+ readonly packApiPath?: string;
77
+
78
+ /**
79
+ * @default "/pack/ws"
80
+ */
81
+ readonly packWsPath?: string;
82
+
83
+ /**
84
+ * Override the base URL from the OSDK client.
85
+ *
86
+ * eg "https://example.com"
87
+ *
88
+ * @default Uses base URL from OSDK client
89
+ */
90
+ readonly baseUrl?: string;
91
+
92
+ /**
93
+ * Override the fetch function from the OSDK client.
94
+ */
95
+ readonly fetchFn?: typeof globalThis.fetch;
96
+ };
97
+ }
@@ -0,0 +1,44 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export type Branded<Brand extends string, T = string> =
18
+ & T
19
+ & Readonly<{
20
+ readonly __pack_brand: Brand;
21
+ }>;
22
+
23
+ /**
24
+ * A type that is "flavored" for self documenting code and prevents some accidental misuse.
25
+ * This is similar to {@link Branded} but allows implicit use of T without a type assertion,
26
+ * which is useful for stronger typing within certain systems without forcing it for all
27
+ * external uses.
28
+ *
29
+ * Flavored types with different brands will not match.
30
+ * A Branded type with the same brand will implicitly match a Flavored type with the same brand,
31
+ * ie `const foo: Flavored<"foo"> = "foo" as Branded<"foo">`
32
+ *
33
+ * @example
34
+ * type MyId = Flavored<"MyId">;
35
+ * type OtherId = Flavored<"OtherId">;
36
+ * const id: MyId = "my-id"; // Good: No type assertion needed
37
+ * const otherId: OtherId = id; // Error: Type 'MyId' is not assignable to type 'OtherId'
38
+ * const otherId: OtherId = id as OtherId; // You can assert between flavored types directly
39
+ */
40
+ export type Flavored<Flavor extends string, T = string> =
41
+ & T
42
+ & Readonly<{
43
+ readonly __pack_brand?: Flavor;
44
+ }>;
@@ -0,0 +1,67 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import type { PackAppInternal } from "./PackApp.js";
18
+
19
+ /**
20
+ * ModuleKey uniquely identifies a module.
21
+ *
22
+ * The key is a symbol and is used to identify the module config.
23
+ * Modules are lazily initialized on first access.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const MY_MODULE_ACCESSOR = "myModule";
28
+ *
29
+ * const MY_MODULE_KEY: ModuleKey<MyModule, MyModuleConfig> = {
30
+ * key: Symbol.for("my.module"),
31
+ *
32
+ * appMemberName: MY_MODULE_ACCESSOR,
33
+ * initModule: initMyModule,
34
+ * };
35
+ *
36
+ * const app = initPackApp({
37
+ * moduleConfig: {
38
+ * [MY_MODULE_KEY.key]: { ... config ... } satisfies MyModuleConfig
39
+ *
40
+ * // Note this is the actual shape of the moduleConfig, ie index by module key symbol
41
+ * // But it is far more ergonomic to spread from a config creator, ie:
42
+ * ...createMyModuleConfig({ ... config ... }),
43
+ * }
44
+ * })
45
+ *
46
+ * // Get the module (manual way)
47
+ * const myModule = app.getModule(MY_MODULE_KEY);
48
+ *
49
+ * // Get the module from app property (available via appMemberName sugar)
50
+ * // You also need to declare the appMemberName on the PackApp interface so the type
51
+ * // system knows it is present. This keeps your module usage limited to where your module
52
+ * // is imported
53
+ * declare module '@palantir/pack.core' {
54
+ * interface PackApp {
55
+ * readonly [MY_MODULE_ACCESSOR]?: MyModule;
56
+ * }
57
+ * }
58
+ * const myModule = app.myModule;
59
+ *
60
+ * ```
61
+ */
62
+ export interface ModuleKey<T, TConfig = unknown> {
63
+ /** If set, this module will have a getter installed on the PackApp interface */
64
+ readonly appMemberName?: string;
65
+ readonly key: symbol;
66
+ readonly initModule: (app: PackAppInternal, config?: TConfig) => T;
67
+ }
@@ -0,0 +1,82 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import invariant from "tiny-invariant";
18
+ import type { AppConfig } from "./AppConfig.js";
19
+ import type { ModuleKey } from "./ModuleKey.js";
20
+
21
+ /**
22
+ * PackApp provides access to various pack subsystems.
23
+ *
24
+ * Specific modules are available after configuration and through declarations mixed in by import.
25
+ * Eg for state system, if you import @palantir/pack.state.core you will have access to `app.state` accessor.
26
+ * Similarly, auth is added automatically by initPackApp.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import { DocumentRef } from '@palantir/pack.state.core';
31
+ * import { DocSchema } from '@my-app/schema';
32
+ *
33
+ * const app = initPackApp({
34
+ * tokenProvider: () => 'your-token',
35
+ * moduleConfigs: {
36
+ * ...createPackDocumentServiceConfig({appId: 'your-app-id', documentType: 'your-document-type'})
37
+ * },
38
+ * });
39
+ *
40
+ * const docRef = app.state.getDocument(docSchema, 'your-document-id');
41
+ * const doc = await docRef.getSnapshot(); // get pojo of your doc state.
42
+ * ```
43
+ */
44
+ export interface PackApp {
45
+ readonly config: AppConfig;
46
+ // Note auth and other module accessors are added dynamically during initialization
47
+ }
48
+
49
+ /**
50
+ * Module configuration - either a tuple of [ModuleKey, config] or just a ModuleKey (for modules with no config)
51
+ */
52
+ export type ModuleConfigTuple<T = unknown> = readonly [ModuleKey<T>, unknown];
53
+ export type ModuleConfig<T = unknown> = ModuleConfigTuple<T> | ModuleKey<T>;
54
+
55
+ /**
56
+ * Type guard to check if a ModuleConfig is a tuple configuration
57
+ */
58
+ export const isModuleConfigTuple = (
59
+ config: ModuleConfig,
60
+ ): config is readonly [ModuleKey<unknown>, unknown] => {
61
+ return Array.isArray(config);
62
+ };
63
+
64
+ export interface PackAppInternal {
65
+ readonly config: AppConfig;
66
+
67
+ /**
68
+ * Internal module accessor
69
+ */
70
+ // TODO: maybe prefix with _ to show it's internal ?
71
+ getModule<T, TConfig = undefined>(moduleKey: ModuleKey<T, TConfig>): T;
72
+ }
73
+
74
+ export function assertIsAppInternal(app: PackApp): asserts app is PackApp & PackAppInternal;
75
+ export function assertIsAppInternal(
76
+ app: PackAppInternal,
77
+ ): asserts app is PackAppInternal;
78
+ export function assertIsAppInternal(
79
+ app: PackApp | PackAppInternal,
80
+ ): asserts app is PackAppInternal {
81
+ invariant("getModule" in app, "App is not an PackAppInternal");
82
+ }
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export type TokenProvider = () => Promise<string>;
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export type Unsubscribe = () => void;
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export function assertNever(_x: never): never {
18
+ throw new Error("Hit unreachable code");
19
+ }
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ function toHexString(byteArray: Int8Array) {
18
+ return Array.from(byteArray, function(byte) {
19
+ const h = (byte & 0xff).toString(16);
20
+ return h.length === 1 ? `0${h}` : h;
21
+ }).join("");
22
+ }
23
+
24
+ export function generateId(bytes = 12): string {
25
+ const array = new Int8Array(bytes);
26
+ const r = crypto.getRandomValues(array);
27
+ return toHexString(r);
28
+ }
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ const SEEN_KEYS = new Set<string>();
18
+
19
+ /**
20
+ * Used to call fn only once between app reloads.
21
+ * eg: Useful for logging warnings that should only be logged once.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * justOnce("unexpected-value", () => console.warn("There was an unexpected value returned", {value}));
26
+ * ```
27
+ */
28
+ export function justOnce(key: string, fn: () => void): void {
29
+ if (!SEEN_KEYS.has(key)) {
30
+ SEEN_KEYS.add(key);
31
+ fn();
32
+ }
33
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "@palantir/pack.monorepo.tsconfig/base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./build/esm",
5
+ "rootDir": "./src",
6
+ "declarationDir": "./build/types",
7
+ "tsBuildInfoFile": "./build/tsconfig.tsbuildinfo"
8
+ },
9
+ "include": [
10
+ "src/**/*"
11
+ ],
12
+ "exclude": [
13
+ "build",
14
+ "dist",
15
+ "node_modules",
16
+ "test-output",
17
+ "**/__tests__/**/__snapshots__",
18
+ "**/__tests__/**/fixtures"
19
+ ],
20
+ "references": []
21
+ }
@@ -0,0 +1,26 @@
1
+ import { coverageConfigDefaults, defaultExclude, defineProject } from "vitest/config";
2
+
3
+ export default defineProject({
4
+ test: {
5
+ exclude: [...defaultExclude, "**/build/**", "**/test-output/**"],
6
+ coverage: {
7
+ provider: "v8",
8
+ all: true,
9
+ enabled: true,
10
+ pool: "forks",
11
+ include: ["src/**/*.{ts,tsx}"],
12
+ exclude: [
13
+ ...coverageConfigDefaults.exclude,
14
+ "**/*.test.{ts,tsx}",
15
+ "**/__tests__",
16
+ "build",
17
+ "coverage",
18
+ "dist",
19
+ "node_modules",
20
+ "src/index.ts",
21
+ "test-output",
22
+ "vitest.config.*",
23
+ ],
24
+ },
25
+ },
26
+ });