@modelnex/sdk 0.5.6 → 0.5.8

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/dist/index.d.mts CHANGED
@@ -315,7 +315,8 @@ interface TagData {
315
315
  interface TagStore {
316
316
  tags: Map<string, TagData>;
317
317
  getTag: (fingerprint: string) => TagData | undefined;
318
- setTag: (fingerprint: string, description: string, category?: TagData['category'], metadata?: Record<string, unknown>, selector?: string, patternId?: string, behavior?: string, sourcePage?: string, displayContext?: string) => void;
318
+ setTag: (fingerprint: string, description: string, category?: TagData['category'], metadata?: Record<string, unknown>, selector?: string, patternId?: string, behavior?: string, sourcePage?: string, displayContext?: string, skipRemoteSync?: boolean) => void;
319
+ setTagsBatch: (tags: TagData[], skipRemoteSync?: boolean) => void;
319
320
  deleteTag: (fingerprint: string) => void;
320
321
  getAllTags: () => TagData[];
321
322
  /** Export all tags as a JSON string (for debugging / backup) */
package/dist/index.d.ts CHANGED
@@ -315,7 +315,8 @@ interface TagData {
315
315
  interface TagStore {
316
316
  tags: Map<string, TagData>;
317
317
  getTag: (fingerprint: string) => TagData | undefined;
318
- setTag: (fingerprint: string, description: string, category?: TagData['category'], metadata?: Record<string, unknown>, selector?: string, patternId?: string, behavior?: string, sourcePage?: string, displayContext?: string) => void;
318
+ setTag: (fingerprint: string, description: string, category?: TagData['category'], metadata?: Record<string, unknown>, selector?: string, patternId?: string, behavior?: string, sourcePage?: string, displayContext?: string, skipRemoteSync?: boolean) => void;
319
+ setTagsBatch: (tags: TagData[], skipRemoteSync?: boolean) => void;
319
320
  deleteTag: (fingerprint: string) => void;
320
321
  getAllTags: () => TagData[];
321
322
  /** Export all tags as a JSON string (for debugging / backup) */
package/dist/index.js CHANGED
@@ -739,32 +739,64 @@ function captureDomSummary(tags) {
739
739
  var import_zod = require("zod");
740
740
  function zodToJsonSchema(schema) {
741
741
  if (!schema) return {};
742
- const def = schema._def;
742
+ const schemaWithCompat = schema;
743
+ if (typeof schemaWithCompat.toJSONSchema === "function") {
744
+ try {
745
+ return schemaWithCompat.toJSONSchema();
746
+ } catch {
747
+ }
748
+ }
749
+ const def = schemaWithCompat._def ?? schemaWithCompat.def;
743
750
  if (!def) return {};
744
- if (def.typeName === import_zod.z.ZodFirstPartyTypeKind.ZodObject) {
745
- const shape = schema.shape;
751
+ const typeName = def.typeName ?? def.type;
752
+ const getShape = (value) => {
753
+ if (value.shape) return value.shape;
754
+ const valueDef = value._def ?? value.def;
755
+ const defShape = valueDef?.shape;
756
+ return typeof defShape === "function" ? defShape() : defShape;
757
+ };
758
+ const getInnerType = (value) => {
759
+ const valueDef = value._def ?? value.def;
760
+ return valueDef?.innerType;
761
+ };
762
+ const getDescription = (value) => {
763
+ const valueWithCompat = value;
764
+ return valueWithCompat.description ?? valueWithCompat._def?.description ?? valueWithCompat.def?.description;
765
+ };
766
+ if (typeName === import_zod.z.ZodFirstPartyTypeKind.ZodObject || typeName === "object") {
767
+ const shape = getShape(schemaWithCompat);
768
+ if (!shape) return {};
746
769
  const properties = {};
747
770
  const required = [];
748
771
  for (const key in shape) {
749
772
  let isOptional = false;
750
773
  let fieldSchema = shape[key];
751
- if (fieldSchema._def.typeName === import_zod.z.ZodFirstPartyTypeKind.ZodOptional) {
774
+ const fieldDef = fieldSchema._def ?? fieldSchema.def;
775
+ const fieldTypeName = fieldDef?.typeName ?? fieldDef?.type;
776
+ if (fieldTypeName === import_zod.z.ZodFirstPartyTypeKind.ZodOptional || fieldTypeName === "optional") {
752
777
  isOptional = true;
753
- fieldSchema = fieldSchema._def.innerType;
778
+ fieldSchema = getInnerType(fieldSchema) ?? fieldSchema;
754
779
  }
755
780
  properties[key] = zodToJsonSchema(fieldSchema);
756
- if (fieldSchema._def.description || shape[key]._def.description) {
757
- properties[key].description = fieldSchema._def.description || shape[key]._def.description;
781
+ const description = getDescription(fieldSchema) ?? getDescription(shape[key]);
782
+ if (description) {
783
+ properties[key].description = description;
758
784
  }
759
785
  if (!isOptional) required.push(key);
760
786
  }
761
787
  return { type: "object", properties, required };
762
788
  }
763
- if (def.typeName === import_zod.z.ZodFirstPartyTypeKind.ZodString) return { type: "string" };
764
- if (def.typeName === import_zod.z.ZodFirstPartyTypeKind.ZodNumber) return { type: "number" };
765
- if (def.typeName === import_zod.z.ZodFirstPartyTypeKind.ZodBoolean) return { type: "boolean" };
766
- if (def.typeName === import_zod.z.ZodFirstPartyTypeKind.ZodEnum) return { type: "string", enum: def.values };
767
- if (def.typeName === import_zod.z.ZodFirstPartyTypeKind.ZodArray) return { type: "array", items: zodToJsonSchema(def.type) };
789
+ if (typeName === import_zod.z.ZodFirstPartyTypeKind.ZodString || typeName === "string") return { type: "string" };
790
+ if (typeName === import_zod.z.ZodFirstPartyTypeKind.ZodNumber || typeName === "number") return { type: "number" };
791
+ if (typeName === import_zod.z.ZodFirstPartyTypeKind.ZodBoolean || typeName === "boolean") return { type: "boolean" };
792
+ if (typeName === import_zod.z.ZodFirstPartyTypeKind.ZodEnum || typeName === "enum") {
793
+ const values = def.values ?? Object.values(def.entries ?? {});
794
+ return { type: "string", enum: values };
795
+ }
796
+ if (typeName === import_zod.z.ZodFirstPartyTypeKind.ZodArray || typeName === "array") {
797
+ const arrayType = def.type ?? def.element;
798
+ return { type: "array", items: zodToJsonSchema(arrayType ?? {}) };
799
+ }
768
800
  return {};
769
801
  }
770
802
  function serializeActions(actions) {
@@ -1240,7 +1272,7 @@ function useTagStore(options) {
1240
1272
  const getTag = (0, import_react6.useCallback)((fingerprint) => {
1241
1273
  return tags.get(fingerprint);
1242
1274
  }, [tags]);
1243
- const setTag = (0, import_react6.useCallback)((fingerprint, description, category, metadata, selector, patternId, behavior, sourcePage, displayContext) => {
1275
+ const setTag = (0, import_react6.useCallback)((fingerprint, description, category, metadata, selector, patternId, behavior, sourcePage, displayContext, skipRemoteSync) => {
1244
1276
  setTags((prev) => {
1245
1277
  const next = new Map(prev);
1246
1278
  const key = selector ? `selector:${selector}` : fingerprint;
@@ -1260,7 +1292,7 @@ function useTagStore(options) {
1260
1292
  updatedAt: now
1261
1293
  };
1262
1294
  next.set(key, tagObj);
1263
- if (apiUrl) {
1295
+ if (apiUrl && !skipRemoteSync) {
1264
1296
  const payload = { tags: [tagObj] };
1265
1297
  if (websiteId) payload.websiteId = websiteId;
1266
1298
  fetch(apiUrl, {
@@ -1272,6 +1304,34 @@ function useTagStore(options) {
1272
1304
  return next;
1273
1305
  });
1274
1306
  }, [apiUrl, websiteId]);
1307
+ const setTagsBatch = (0, import_react6.useCallback)((newTags, skipRemoteSync) => {
1308
+ setTags((prev) => {
1309
+ const next = new Map(prev);
1310
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1311
+ const updatedTags = [];
1312
+ for (const t of newTags) {
1313
+ const key = t.selector ? `selector:${t.selector}` : t.fingerprint;
1314
+ const existing = prev.get(key);
1315
+ const tagObj = {
1316
+ ...t,
1317
+ createdAt: existing?.createdAt ?? t.createdAt ?? now,
1318
+ updatedAt: now
1319
+ };
1320
+ next.set(key, tagObj);
1321
+ updatedTags.push(tagObj);
1322
+ }
1323
+ if (apiUrl && !skipRemoteSync && updatedTags.length > 0) {
1324
+ const payload = { tags: updatedTags };
1325
+ if (websiteId) payload.websiteId = websiteId;
1326
+ fetch(apiUrl, {
1327
+ method: "POST",
1328
+ headers: { "Content-Type": "application/json" },
1329
+ body: JSON.stringify(payload)
1330
+ }).catch((err) => console.warn("[ModelNex] Failed to save remote tags batch:", err));
1331
+ }
1332
+ return next;
1333
+ });
1334
+ }, [apiUrl, websiteId]);
1275
1335
  const deleteTag = (0, import_react6.useCallback)((fingerprint) => {
1276
1336
  setTags((prev) => {
1277
1337
  const next = new Map(prev);
@@ -1301,7 +1361,7 @@ function useTagStore(options) {
1301
1361
  console.warn("[ModelNex] Failed to import tags:", err);
1302
1362
  }
1303
1363
  }, []);
1304
- return { tags, getTag, setTag, deleteTag, getAllTags, exportTags, importTags };
1364
+ return { tags, getTag, setTag, setTagsBatch, deleteTag, getAllTags, exportTags, importTags };
1305
1365
  }
1306
1366
 
1307
1367
  // src/studio-mode.tsx
@@ -8448,21 +8508,7 @@ function ModelNexChatBubble({
8448
8508
  });
8449
8509
  const data = await resp.json();
8450
8510
  if (data.success && Array.isArray(data.tags)) {
8451
- for (const tag of data.tags) {
8452
- if (tag.patternId && tag.description && tag.selector) {
8453
- tagStore.setTag(
8454
- "",
8455
- tag.description,
8456
- tag.category || "other",
8457
- { matchedFingerprints: tag.matchedFingerprints },
8458
- tag.selector,
8459
- tag.patternId,
8460
- tag.behavior || void 0,
8461
- tag.sourcePage || void 0,
8462
- tag.displayContext || void 0
8463
- );
8464
- }
8465
- }
8511
+ tagStore.setTagsBatch(data.tags, true);
8466
8512
  lastAutoTaggedUrlRef.current = currentUrl;
8467
8513
  localStorage.setItem(storageKey, "true");
8468
8514
  console.log(`[ModelNex] Auto-tagged ${data.tags.length} elements for ${currentUrl}`);
package/dist/index.mjs CHANGED
@@ -530,32 +530,64 @@ function captureDomSummary(tags) {
530
530
  import { z } from "zod";
531
531
  function zodToJsonSchema(schema) {
532
532
  if (!schema) return {};
533
- const def = schema._def;
533
+ const schemaWithCompat = schema;
534
+ if (typeof schemaWithCompat.toJSONSchema === "function") {
535
+ try {
536
+ return schemaWithCompat.toJSONSchema();
537
+ } catch {
538
+ }
539
+ }
540
+ const def = schemaWithCompat._def ?? schemaWithCompat.def;
534
541
  if (!def) return {};
535
- if (def.typeName === z.ZodFirstPartyTypeKind.ZodObject) {
536
- const shape = schema.shape;
542
+ const typeName = def.typeName ?? def.type;
543
+ const getShape = (value) => {
544
+ if (value.shape) return value.shape;
545
+ const valueDef = value._def ?? value.def;
546
+ const defShape = valueDef?.shape;
547
+ return typeof defShape === "function" ? defShape() : defShape;
548
+ };
549
+ const getInnerType = (value) => {
550
+ const valueDef = value._def ?? value.def;
551
+ return valueDef?.innerType;
552
+ };
553
+ const getDescription = (value) => {
554
+ const valueWithCompat = value;
555
+ return valueWithCompat.description ?? valueWithCompat._def?.description ?? valueWithCompat.def?.description;
556
+ };
557
+ if (typeName === z.ZodFirstPartyTypeKind.ZodObject || typeName === "object") {
558
+ const shape = getShape(schemaWithCompat);
559
+ if (!shape) return {};
537
560
  const properties = {};
538
561
  const required = [];
539
562
  for (const key in shape) {
540
563
  let isOptional = false;
541
564
  let fieldSchema = shape[key];
542
- if (fieldSchema._def.typeName === z.ZodFirstPartyTypeKind.ZodOptional) {
565
+ const fieldDef = fieldSchema._def ?? fieldSchema.def;
566
+ const fieldTypeName = fieldDef?.typeName ?? fieldDef?.type;
567
+ if (fieldTypeName === z.ZodFirstPartyTypeKind.ZodOptional || fieldTypeName === "optional") {
543
568
  isOptional = true;
544
- fieldSchema = fieldSchema._def.innerType;
569
+ fieldSchema = getInnerType(fieldSchema) ?? fieldSchema;
545
570
  }
546
571
  properties[key] = zodToJsonSchema(fieldSchema);
547
- if (fieldSchema._def.description || shape[key]._def.description) {
548
- properties[key].description = fieldSchema._def.description || shape[key]._def.description;
572
+ const description = getDescription(fieldSchema) ?? getDescription(shape[key]);
573
+ if (description) {
574
+ properties[key].description = description;
549
575
  }
550
576
  if (!isOptional) required.push(key);
551
577
  }
552
578
  return { type: "object", properties, required };
553
579
  }
554
- if (def.typeName === z.ZodFirstPartyTypeKind.ZodString) return { type: "string" };
555
- if (def.typeName === z.ZodFirstPartyTypeKind.ZodNumber) return { type: "number" };
556
- if (def.typeName === z.ZodFirstPartyTypeKind.ZodBoolean) return { type: "boolean" };
557
- if (def.typeName === z.ZodFirstPartyTypeKind.ZodEnum) return { type: "string", enum: def.values };
558
- if (def.typeName === z.ZodFirstPartyTypeKind.ZodArray) return { type: "array", items: zodToJsonSchema(def.type) };
580
+ if (typeName === z.ZodFirstPartyTypeKind.ZodString || typeName === "string") return { type: "string" };
581
+ if (typeName === z.ZodFirstPartyTypeKind.ZodNumber || typeName === "number") return { type: "number" };
582
+ if (typeName === z.ZodFirstPartyTypeKind.ZodBoolean || typeName === "boolean") return { type: "boolean" };
583
+ if (typeName === z.ZodFirstPartyTypeKind.ZodEnum || typeName === "enum") {
584
+ const values = def.values ?? Object.values(def.entries ?? {});
585
+ return { type: "string", enum: values };
586
+ }
587
+ if (typeName === z.ZodFirstPartyTypeKind.ZodArray || typeName === "array") {
588
+ const arrayType = def.type ?? def.element;
589
+ return { type: "array", items: zodToJsonSchema(arrayType ?? {}) };
590
+ }
559
591
  return {};
560
592
  }
561
593
  function serializeActions(actions) {
@@ -1031,7 +1063,7 @@ function useTagStore(options) {
1031
1063
  const getTag = useCallback3((fingerprint) => {
1032
1064
  return tags.get(fingerprint);
1033
1065
  }, [tags]);
1034
- const setTag = useCallback3((fingerprint, description, category, metadata, selector, patternId, behavior, sourcePage, displayContext) => {
1066
+ const setTag = useCallback3((fingerprint, description, category, metadata, selector, patternId, behavior, sourcePage, displayContext, skipRemoteSync) => {
1035
1067
  setTags((prev) => {
1036
1068
  const next = new Map(prev);
1037
1069
  const key = selector ? `selector:${selector}` : fingerprint;
@@ -1051,7 +1083,7 @@ function useTagStore(options) {
1051
1083
  updatedAt: now
1052
1084
  };
1053
1085
  next.set(key, tagObj);
1054
- if (apiUrl) {
1086
+ if (apiUrl && !skipRemoteSync) {
1055
1087
  const payload = { tags: [tagObj] };
1056
1088
  if (websiteId) payload.websiteId = websiteId;
1057
1089
  fetch(apiUrl, {
@@ -1063,6 +1095,34 @@ function useTagStore(options) {
1063
1095
  return next;
1064
1096
  });
1065
1097
  }, [apiUrl, websiteId]);
1098
+ const setTagsBatch = useCallback3((newTags, skipRemoteSync) => {
1099
+ setTags((prev) => {
1100
+ const next = new Map(prev);
1101
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1102
+ const updatedTags = [];
1103
+ for (const t of newTags) {
1104
+ const key = t.selector ? `selector:${t.selector}` : t.fingerprint;
1105
+ const existing = prev.get(key);
1106
+ const tagObj = {
1107
+ ...t,
1108
+ createdAt: existing?.createdAt ?? t.createdAt ?? now,
1109
+ updatedAt: now
1110
+ };
1111
+ next.set(key, tagObj);
1112
+ updatedTags.push(tagObj);
1113
+ }
1114
+ if (apiUrl && !skipRemoteSync && updatedTags.length > 0) {
1115
+ const payload = { tags: updatedTags };
1116
+ if (websiteId) payload.websiteId = websiteId;
1117
+ fetch(apiUrl, {
1118
+ method: "POST",
1119
+ headers: { "Content-Type": "application/json" },
1120
+ body: JSON.stringify(payload)
1121
+ }).catch((err) => console.warn("[ModelNex] Failed to save remote tags batch:", err));
1122
+ }
1123
+ return next;
1124
+ });
1125
+ }, [apiUrl, websiteId]);
1066
1126
  const deleteTag = useCallback3((fingerprint) => {
1067
1127
  setTags((prev) => {
1068
1128
  const next = new Map(prev);
@@ -1092,7 +1152,7 @@ function useTagStore(options) {
1092
1152
  console.warn("[ModelNex] Failed to import tags:", err);
1093
1153
  }
1094
1154
  }, []);
1095
- return { tags, getTag, setTag, deleteTag, getAllTags, exportTags, importTags };
1155
+ return { tags, getTag, setTag, setTagsBatch, deleteTag, getAllTags, exportTags, importTags };
1096
1156
  }
1097
1157
 
1098
1158
  // src/studio-mode.tsx
@@ -8238,21 +8298,7 @@ function ModelNexChatBubble({
8238
8298
  });
8239
8299
  const data = await resp.json();
8240
8300
  if (data.success && Array.isArray(data.tags)) {
8241
- for (const tag of data.tags) {
8242
- if (tag.patternId && tag.description && tag.selector) {
8243
- tagStore.setTag(
8244
- "",
8245
- tag.description,
8246
- tag.category || "other",
8247
- { matchedFingerprints: tag.matchedFingerprints },
8248
- tag.selector,
8249
- tag.patternId,
8250
- tag.behavior || void 0,
8251
- tag.sourcePage || void 0,
8252
- tag.displayContext || void 0
8253
- );
8254
- }
8255
- }
8301
+ tagStore.setTagsBatch(data.tags, true);
8256
8302
  lastAutoTaggedUrlRef.current = currentUrl;
8257
8303
  localStorage.setItem(storageKey, "true");
8258
8304
  console.log(`[ModelNex] Auto-tagged ${data.tags.length} elements for ${currentUrl}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelnex/sdk",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "description": "React SDK for natural language control of web apps via AI agents",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",