Skip to content

Commit fa0396d

Browse files
committed
chore: Align isObject/isRecord usage
1 parent c9927e0 commit fa0396d

File tree

22 files changed

+84
-85
lines changed

22 files changed

+84
-85
lines changed

background-charm-service/src/space-manager.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { sleep } from "@commontools/utils";
1+
import { sleep } from "@commontools/utils/sleep";
22
import { Cell } from "@commontools/runner";
33
import { type Cancel, useCancelGroup } from "@commontools/runner";
44
import {

builder/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export {
3838
ID,
3939
ID_FIELD,
4040
isAlias,
41+
isJSONSchema,
4142
isModule,
4243
isOpaqueRef,
4344
isRecipe,

builder/src/types.ts

+24-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { isObj } from "@commontools/utils";
2-
import { Mutable } from "@commontools/utils/types";
1+
import { isObject, Mutable } from "@commontools/utils/types";
32

43
export const ID: unique symbol = Symbol("ID, unique to the context");
54
export const ID_FIELD: unique symbol = Symbol(
@@ -153,6 +152,27 @@ export type JSONSchema = {
153152
readonly ifc?: { classification?: string[]; integrity?: string[] }; // temporarily used to assign labels like "confidential"
154153
};
155154

155+
export const isJSONSchema = (source: unknown): source is JSONSchema => {
156+
if (!isObject(source)) {
157+
return false;
158+
}
159+
160+
if (!("type" in source) || !source.type) {
161+
return "anyOf" in source && Array.isArray(source.anyOf);
162+
}
163+
switch (source.type) {
164+
case "object":
165+
case "array":
166+
case "string":
167+
case "integer":
168+
case "number":
169+
case "boolean":
170+
case "null":
171+
return true;
172+
}
173+
return false;
174+
};
175+
156176
export { type Mutable };
157177
export type JSONSchemaMutable = Mutable<JSONSchema>;
158178

@@ -166,7 +186,8 @@ export type Alias = {
166186
};
167187

168188
export function isAlias(value: any): value is Alias {
169-
return isObj(value) && isObj(value.$alias) &&
189+
return isObject(value) && "$alias" in value && isObject(value.$alias) &&
190+
"path" in value.$alias &&
170191
Array.isArray(value.$alias.path);
171192
}
172193

charm/src/iterate.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
recipeManager,
66
runtime,
77
} from "@commontools/runner";
8-
import { isObj } from "@commontools/utils";
8+
import { isObject } from "@commontools/utils/types";
99
import {
1010
createJsonSchema,
1111
JSONSchema,
@@ -215,7 +215,7 @@ export function scrub(data: any): any {
215215
// If there are properties, remove $UI and $NAME and any streams
216216
const scrubbed = Object.fromEntries(
217217
Object.entries(data.schema.properties).filter(([key, value]) =>
218-
!key.startsWith("$") && (!isObj(value) || !value.asStream)
218+
!key.startsWith("$") && (!isObject(value) || !value.asStream)
219219
),
220220
);
221221
console.log("scrubbed modified schema", scrubbed, data.schema);
@@ -227,7 +227,7 @@ export function scrub(data: any): any {
227227
);
228228
} else {
229229
const value = data.asSchema().get();
230-
if (isObj(value)) {
230+
if (isObject(value)) {
231231
// Generate a new schema for all properties except $UI and $NAME and streams
232232
const scrubbed = {
233233
type: "object",
@@ -248,7 +248,7 @@ export function scrub(data: any): any {
248248
}
249249
} else if (Array.isArray(data)) {
250250
return data.map((value) => scrub(value));
251-
} else if (isObj(data)) {
251+
} else if (isObject(data)) {
252252
return Object.fromEntries(
253253
Object.entries(data).map(([key, value]) => [key, scrub(value)]),
254254
);
@@ -264,7 +264,7 @@ function turnCellsIntoAliases(data: any): any {
264264
return { $alias: data.getAsCellLink() };
265265
} else if (Array.isArray(data)) {
266266
return data.map((value) => turnCellsIntoAliases(value));
267-
} else if (isObj(data)) {
267+
} else if (isObject(data)) {
268268
return Object.fromEntries(
269269
Object.entries(data).map((
270270
[key, value],

charm/src/manager.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
} from "@commontools/runner";
2828
import { storage } from "@commontools/runner";
2929
import { type Session } from "@commontools/identity";
30-
import { isObj } from "@commontools/utils";
30+
import { isObject } from "@commontools/utils/types";
3131

3232
export function charmId(charm: Charm): string | undefined {
3333
const id = getEntityId(charm);
@@ -343,7 +343,7 @@ export class CharmManager {
343343
// If there is no result schema, create one from top level properties that omits UI, NAME
344344
if (!resultSchema) {
345345
const resultValue = charm.get();
346-
if (isObj(resultValue)) {
346+
if (isObject(resultValue)) {
347347
resultSchema = {
348348
type: "object",
349349
properties: Object.fromEntries(

html/deno.json renamed to html/deno.jsonc

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "@commontools/html",
33
"exports": "./src/index.ts",
44
"tasks": {
5+
// JSDOM dependencies require env.
56
"test": "deno test --allow-env"
67
},
78
"imports": {

html/src/path.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import * as logger from "./logger.ts";
2-
3-
export const isObject = (value: unknown): value is object => {
4-
return typeof value === "object" && value !== null;
5-
};
2+
import { isObject } from "@commontools/utils/types";
63

74
/** A keypath is an array of property keys */
85
export type KeyPath = Array<PropertyKey>;

html/src/render.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
useCancelGroup,
99
} from "@commontools/runner";
1010
import { JSONSchema } from "@commontools/builder";
11-
import { isObj } from "@commontools/utils";
11+
import { isObject } from "@commontools/utils/types";
1212
import * as logger from "./logger.ts";
1313

1414
const vdomSchema: JSONSchema = {
@@ -271,7 +271,7 @@ const sanitizeScripts = (node: VNode): VNode | null => {
271271
if (node.name === "script") {
272272
return null;
273273
}
274-
if (!isCell(node.props) && !isObj(node.props)) {
274+
if (!isCell(node.props) && !isObject(node.props)) {
275275
node = { ...node, props: {} };
276276
}
277277
if (!isCell(node.children) && !Array.isArray(node.children)) {

html/test/assert.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { isRecord } from "@commontools/utils/types";
2+
13
export class AssertionError<A, E> extends Error {
24
actual: A | undefined;
35
expected: E | undefined;
@@ -43,7 +45,7 @@ export const matchObject = (
4345
expected: unknown,
4446
message = "",
4547
) => {
46-
if (!isObject(actual) || !isObject(expected)) {
48+
if (!isRecord(actual) || !isRecord(expected)) {
4749
throw new AssertionError({
4850
message: message || "Both arguments must be objects",
4951
actual,
@@ -61,7 +63,7 @@ export const matchObject = (
6163
});
6264
}
6365

64-
if (isObject(expected[key]) && isObject(actual[key])) {
66+
if (isRecord(expected[key]) && isRecord(actual[key])) {
6567
// Recursively check nested objects
6668
matchObject(actual[key], expected[key], message);
6769
} else if (actual[key] !== expected[key]) {
@@ -84,10 +86,6 @@ export const matchObject = (
8486
}
8587
};
8688

87-
function isObject(value: unknown): value is Record<string, unknown> {
88-
return typeof value === "object" && value !== null;
89-
}
90-
9189
export const throws = (run: () => void, message = "") => {
9290
try {
9391
run();

iframe-sandbox/src/ipc.ts

+6-27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { type JSONSchema } from "@commontools/builder";
1+
import { isJSONSchema, type JSONSchema } from "@commontools/builder";
2+
import { isObject } from "@commontools/utils/types";
23

34
// Types used by the `common-iframe-sandbox` IPC.
45

@@ -107,34 +108,12 @@ export function isGuestError(e: object): e is GuestError {
107108
"stacktrace" in e && typeof e.stacktrace === "string";
108109
}
109110

110-
const isObject = (source: unknown): source is Record<string, unknown> =>
111-
typeof source === "object" && source != null;
112111
export const isTaskPerform = (source: unknown): source is TaskPerform =>
113112
isObject(source) &&
114-
typeof source?.intent === "string" &&
115-
typeof source?.description === "string" &&
116-
isObject(source?.input) &&
117-
isJSONSchema(source?.output);
118-
119-
export const isJSONSchema = (source: unknown): source is JSONSchema => {
120-
if (!isObject(source)) {
121-
return false;
122-
}
123-
124-
switch (source?.type) {
125-
case "object":
126-
case "array":
127-
case "string":
128-
case "integer":
129-
case "number":
130-
case "boolean":
131-
case "null":
132-
return true;
133-
default: {
134-
return Array.isArray(source?.anyOf);
135-
}
136-
}
137-
};
113+
"intent" in source && typeof source.intent === "string" &&
114+
"description" in source && typeof source.description === "string" &&
115+
"input" in source && isObject(source.input) &&
116+
"output" in source && isJSONSchema(source.output);
138117

139118
export enum HostMessageType {
140119
Ping = "ping",

jumble/src/iframe-ctx.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
removeAction,
1515
} from "@commontools/runner";
1616
import { DEFAULT_IFRAME_MODELS, LLMClient } from "@commontools/llm";
17-
import { isObj } from "@commontools/utils";
17+
import { isObject } from "@commontools/utils/types";
1818
import {
1919
completeJob,
2020
failJob,
@@ -196,7 +196,7 @@ export const setupIframe = () =>
196196
: undefined;
197197
const type = context.key(key).schema?.type ??
198198
currentValueType ?? typeof value;
199-
if (type === "object" && isObj(value) && !Array.isArray(value)) {
199+
if (type === "object" && isObject(value)) {
200200
context.key(key).update(value);
201201
} else if (
202202
(type === "array" && Array.isArray(value)) ||

jumble/src/views/CharmDetailView.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from "@commontools/charm";
88
import { useCharmReferences } from "@/hooks/use-charm-references.ts";
99
import { isCell, isStream } from "@commontools/runner";
10-
import { isObj } from "@commontools/utils";
10+
import { isObject } from "@commontools/utils/types";
1111
import {
1212
CheckboxToggle,
1313
CommonCheckbox,
@@ -1339,7 +1339,7 @@ function translateCellsAndStreamsToPlainJSON(
13391339
result = data.map((value) =>
13401340
translateCellsAndStreamsToPlainJSON(value, partial, complete)
13411341
);
1342-
} else if (isObj(data)) {
1342+
} else if (isObject(data)) {
13431343
result = Object.fromEntries(
13441344
Object.entries(data).map(([key, value]) => [
13451345
key,

memory/space-schema.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
SchemaContext,
1010
SchemaQuery,
1111
} from "./interface.ts";
12-
import { isNumber, isObject, isString } from "./util.ts";
12+
import { isNumber, isObject, isString } from "@commontools/utils/types";
1313
import { FactSelector, SelectAll, selectFacts, Session } from "./space.ts";
1414
import { FactAddress } from "../runner/src/storage/cache.ts";
1515
import {

memory/traverse.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import { isAlias } from "../builder/src/index.ts";
55
import { JSONObject, JSONValue } from "./consumer.ts";
6-
import { isObject } from "./provider.ts";
6+
import { isObject } from "@commontools/utils/types";
77

88
export class CycleTracker<K> {
99
private partial: Set<K>;
@@ -361,7 +361,8 @@ export function isPointer(value: any): boolean {
361361
* @returns {boolean}
362362
*/
363363
function isJSONCellLink(value: any): value is JSONCellLink {
364-
return (isObject(value) && isObject(value.cell) && "/" in value.cell &&
364+
return (isObject(value) && "cell" in value && isObject(value.cell) &&
365+
"/" in value.cell && "path" in value &&
365366
Array.isArray(value.path));
366367
}
367368

memory/util.ts

-12
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,3 @@ export const fromDID = async <ID extends DIDKey>(
4141
}
4242
}
4343
};
44-
45-
export function isObject(value: unknown): boolean {
46-
return typeof value === "object" && value !== null && !Array.isArray(value);
47-
}
48-
49-
export function isNumber(value: unknown): value is number {
50-
return typeof value === "number" && Number.isFinite(value);
51-
}
52-
53-
export function isString(value: unknown): value is string {
54-
return typeof value === "string";
55-
}

runner/src/cfc.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// This is a simple form of the policy, where you express the basics of the partial ordering.
22

33
import type { JSONSchema, JSONValue } from "@commontools/builder";
4-
import { isObject } from "../../memory/util.ts";
4+
import { isObject } from "@commontools/utils/types";
55
import { extractDefaultValues } from "./utils.ts";
66

77
// We'll often work with the transitive closure of this graph.

runner/src/storage.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ import { VolatileStorageProvider } from "./storage/volatile.ts";
2222
import { Signer } from "@commontools/identity";
2323
import { isBrowser } from "@commontools/utils/env";
2424
import { sleep } from "@commontools/utils/sleep";
25+
import { defer } from "@commontools/utils/defer";
2526
import { TransactionResult } from "@commontools/memory";
2627
import { refer } from "@commontools/memory/reference";
27-
import { defer } from "@commontools/utils";
2828
import { SchemaContext, SchemaNone } from "@commontools/memory/interface";
2929

3030
export function log(fn: () => any[]) {

toolshed/routes/ai/spell/handlers/find-spell-by-schema.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { captureException } from "@sentry/deno";
1212
import { FindSpellBySchemaRequest } from "@/routes/ai/spell/spell.handlers.ts";
1313

1414
import { checkSchemaMatch } from "@/lib/schema-match.ts";
15-
import { isObject } from "@/routes/ai/spell/schema.ts";
15+
import { isObject } from "@commontools/utils/types";
1616
import { Schema } from "jsonschema";
1717
import { Recipe, RecipeSchema } from "../spell.ts";
1818

toolshed/routes/ai/spell/schema.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { checkSchemaMatch } from "@/lib/schema-match.ts";
22
import { Logger } from "@/lib/prefixed-logger.ts";
3+
import { isObject } from "@commontools/utils/types";
34

45
export interface SchemaMatch<T = Record<string, unknown>> {
56
key: string;
@@ -91,10 +92,6 @@ export function findExactSubtreeMatches(
9192
return matches;
9293
}
9394

94-
export function isObject(value: unknown): boolean {
95-
return typeof value === "object" && value !== null && !Array.isArray(value);
96-
}
97-
9895
export function decomposeSchema(
9996
schema: Record<string, unknown>,
10097
parentPath: string[] = [],

utils/src/index.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
export * from "./defer.ts";
2-
export * from "./env.ts";
3-
export * from "./isObj.ts";
4-
export * from "./sleep.ts";
1+
throw new Error(`Import individual exports for utils: \`import { defer } from "@commontools/utils/defer"\``);

utils/src/isObj.ts

-5
This file was deleted.

0 commit comments

Comments
 (0)