@coasys/ad4m-connect 0.13.0-postmessage-ws-proxy.1 → 0.13.0-postmessage-ws-proxy.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/dist/index.js CHANGED
@@ -130,7 +130,7 @@ var _PostMessageWebSocket = class {
130
130
  this._connectTimeout = null;
131
131
  this._targetOrigin = targetOrigin;
132
132
  this._messageHandler = (e7) => {
133
- var _a, _b, _c, _d;
133
+ var _a, _b, _c, _d, _e;
134
134
  if (e7.source !== window.parent)
135
135
  return;
136
136
  if (e7.origin !== this._targetOrigin)
@@ -150,13 +150,16 @@ var _PostMessageWebSocket = class {
150
150
  }
151
151
  if (msg.type === "AD4M_PROXY_WS_ERROR") {
152
152
  this._clearConnectTimeout();
153
+ this.readyState = _PostMessageWebSocket.CLOSED;
154
+ window.removeEventListener("message", this._messageHandler);
153
155
  (_c = this.onerror) == null ? void 0 : _c.call(this, new Event("error"));
156
+ (_d = this.onclose) == null ? void 0 : _d.call(this, new CloseEvent("close", { code: 1006, reason: "WebSocket error", wasClean: false }));
154
157
  return;
155
158
  }
156
159
  if (msg.type === "AD4M_PROXY_WS_CLOSED") {
157
160
  this._clearConnectTimeout();
158
161
  this.readyState = 3;
159
- (_d = this.onclose) == null ? void 0 : _d.call(
162
+ (_e = this.onclose) == null ? void 0 : _e.call(
160
163
  this,
161
164
  new CloseEvent("close", {
162
165
  code: typeof msg.code === "number" ? msg.code : 1e3,
@@ -1194,6 +1197,41 @@ var SHACLShape = class {
1194
1197
  target: `literal:string:${JSON.stringify(prop.in)}`
1195
1198
  });
1196
1199
  }
1200
+ if (prop.relationKind) {
1201
+ links.push({
1202
+ source: propShapeId,
1203
+ predicate: "ad4m://relationKind",
1204
+ target: `literal:string:${prop.relationKind}`
1205
+ });
1206
+ }
1207
+ if (prop.targetClassName) {
1208
+ links.push({
1209
+ source: propShapeId,
1210
+ predicate: "ad4m://targetClassName",
1211
+ target: `literal:string:${prop.targetClassName}`
1212
+ });
1213
+ }
1214
+ if (prop.whereFilter !== void 0 && prop.whereFilter !== null) {
1215
+ links.push({
1216
+ source: propShapeId,
1217
+ predicate: "ad4m://whereFilter",
1218
+ target: `literal:string:${JSON.stringify(prop.whereFilter)}`
1219
+ });
1220
+ }
1221
+ if (prop.wherePredicates && Object.keys(prop.wherePredicates).length > 0) {
1222
+ links.push({
1223
+ source: propShapeId,
1224
+ predicate: "ad4m://wherePredicates",
1225
+ target: `literal:string:${JSON.stringify(prop.wherePredicates)}`
1226
+ });
1227
+ }
1228
+ if (prop.filter !== void 0) {
1229
+ links.push({
1230
+ source: propShapeId,
1231
+ predicate: "ad4m://filter",
1232
+ target: `literal:${prop.filter}`
1233
+ });
1234
+ }
1197
1235
  }
1198
1236
  return links;
1199
1237
  }
@@ -1342,6 +1380,40 @@ var SHACLShape = class {
1342
1380
  } catch (e7) {
1343
1381
  }
1344
1382
  }
1383
+ const relationKindLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://relationKind");
1384
+ if (relationKindLink) {
1385
+ const val = relationKindLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
1386
+ if (val === "hasMany" || val === "hasOne" || val === "belongsToOne" || val === "belongsToMany") {
1387
+ prop.relationKind = val;
1388
+ }
1389
+ }
1390
+ const targetClassNameLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://targetClassName");
1391
+ if (targetClassNameLink) {
1392
+ prop.targetClassName = targetClassNameLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
1393
+ }
1394
+ const whereFilterLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://whereFilter");
1395
+ if (whereFilterLink) {
1396
+ try {
1397
+ const jsonStr = whereFilterLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
1398
+ prop.whereFilter = JSON.parse(jsonStr);
1399
+ } catch (e7) {
1400
+ }
1401
+ }
1402
+ const wherePredicatesLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://wherePredicates");
1403
+ if (wherePredicatesLink) {
1404
+ try {
1405
+ const jsonStr = wherePredicatesLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
1406
+ prop.wherePredicates = JSON.parse(jsonStr);
1407
+ } catch (e7) {
1408
+ }
1409
+ }
1410
+ const filterLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://filter");
1411
+ if (filterLink) {
1412
+ let val = filterLink.target.replace(/^literal:\/\/|^literal:/, "");
1413
+ if (val.startsWith("boolean:"))
1414
+ val = val.substring(8);
1415
+ prop.filter = val === "true";
1416
+ }
1345
1417
  shape.addProperty(prop);
1346
1418
  }
1347
1419
  return shape;
@@ -1371,7 +1443,12 @@ var SHACLShape = class {
1371
1443
  getter: p2.getter,
1372
1444
  conformance_conditions: p2.conformanceConditions,
1373
1445
  class: p2.class,
1374
- in: p2.in
1446
+ in: p2.in,
1447
+ relation_kind: p2.relationKind,
1448
+ target_class_name: p2.targetClassName,
1449
+ where_filter: p2.whereFilter,
1450
+ where_predicates: p2.wherePredicates,
1451
+ filter: p2.filter
1375
1452
  })),
1376
1453
  constructor_actions: this.constructor_actions,
1377
1454
  destructor_actions: this.destructor_actions
@@ -1400,7 +1477,12 @@ var SHACLShape = class {
1400
1477
  getter: p2.getter,
1401
1478
  conformanceConditions: p2.conformance_conditions,
1402
1479
  class: p2.class,
1403
- in: p2.in
1480
+ in: p2.in,
1481
+ relationKind: p2.relation_kind,
1482
+ targetClassName: p2.target_class_name,
1483
+ whereFilter: p2.where_filter,
1484
+ wherePredicates: p2.where_predicates,
1485
+ filter: p2.filter
1404
1486
  });
1405
1487
  }
1406
1488
  if (json.constructor_actions) {
@@ -1417,114 +1499,9 @@ var SHACLShape = class {
1417
1499
  return shape;
1418
1500
  }
1419
1501
  };
1420
- function formatList(list) {
1421
- if (!list?.length) {
1422
- return "";
1423
- }
1424
- if (list.length === 1) {
1425
- return list.toString();
1426
- }
1427
- if (list.length === 2) {
1428
- return list.join(" and ");
1429
- }
1430
- return list.slice(0, -1).join(", ") + ", and " + list.slice(-1);
1431
- }
1432
- function capSentence(cap) {
1433
- const can = cap.can.includes("*") ? ["READ", "WRITE", "UPDATE"] : cap.can;
1434
- const domain = cap.with.domain === "*" ? "" : cap.with.domain;
1435
- const pointers = cap.with.pointers.includes("*") ? ["all AD4M data"] : cap.with.pointers;
1436
- return `${formatList(can)} your ${domain} actions, with access to ${formatList(pointers)}`;
1437
- }
1438
- function escapeQueryString(value) {
1439
- return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
1440
- }
1441
- function buildWhereCondition(predicate, condition, opts) {
1442
- const escapedPredicate = escapeQueryString(predicate);
1443
- const isLiteral = !opts?.resolveLanguage || opts.resolveLanguage === "literal";
1444
- const varSuffix = opts?.varIndex ?? 0;
1445
- function formatValue(v2) {
1446
- if (typeof v2 === "string") {
1447
- return isLiteral ? `<literal:string:${escapeQueryString(v2)}>` : `<${escapeQueryString(v2)}>`;
1448
- }
1449
- return `<literal:string:${v2}>`;
1450
- }
1451
- function formatLiteralFilter(varName, v2) {
1452
- const raw = escapeQueryString(String(v2));
1453
- const encoded = encodeURIComponent(String(v2)).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A");
1454
- if (typeof v2 === "string") {
1455
- return `FILTER(STR(${varName}) = "${raw}" || STR(${varName}) = "literal:string:${encoded}")`;
1456
- } else if (typeof v2 === "number") {
1457
- return `FILTER(STR(${varName}) = "${v2}" || STR(${varName}) = "literal:number:${v2}")`;
1458
- } else if (typeof v2 === "boolean") {
1459
- return `FILTER(STR(${varName}) = "${v2}" || STR(${varName}) = "literal:boolean:${v2}")`;
1460
- }
1461
- return `FILTER(STR(${varName}) = "${raw}")`;
1462
- }
1463
- if (Array.isArray(condition)) {
1464
- if (isLiteral) {
1465
- const varName = `?_wc${varSuffix}`;
1466
- const inValues = condition.flatMap((v2) => {
1467
- const raw = escapeQueryString(String(v2));
1468
- const encoded = encodeURIComponent(String(v2)).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A");
1469
- return [`"${raw}"`, `"literal:string:${encoded}"`];
1470
- }).join(", ");
1471
- return `?target <${escapedPredicate}> ${varName} . FILTER(STR(${varName}) IN (${inValues}))`;
1472
- }
1473
- const formattedValues = condition.map(formatValue).join(", ");
1474
- return `FILTER EXISTS { ?target <${escapedPredicate}> ?_val . FILTER(?_val IN (${formattedValues})) }`;
1475
- } else if (typeof condition === "object" && condition !== null) {
1476
- const ops = condition;
1477
- const parts = [];
1478
- if (ops.not !== void 0) {
1479
- if (Array.isArray(ops.not)) {
1480
- const formattedValues = ops.not.map((v2) => formatValue(v2)).join(", ");
1481
- parts.push(`FILTER NOT EXISTS { ?target <${escapedPredicate}> ?_nval . FILTER(?_nval IN (${formattedValues})) }`);
1482
- } else {
1483
- parts.push(`FILTER NOT EXISTS { ?target <${escapedPredicate}> ${formatValue(ops.not)} }`);
1484
- }
1485
- }
1486
- const hasComparisonOps = ops.gt !== void 0 || ops.gte !== void 0 || ops.lt !== void 0 || ops.lte !== void 0 || ops.between !== void 0 || ops.contains !== void 0;
1487
- if (hasComparisonOps) {
1488
- parts.push(`FILTER EXISTS { ?target <${escapedPredicate}> ?_cmp }`);
1489
- }
1490
- return parts.join(" ");
1491
- } else {
1492
- if (isLiteral) {
1493
- const varName = `?_wc${varSuffix}`;
1494
- return `?target <${escapedPredicate}> ${varName} . ${formatLiteralFilter(varName, condition)}`;
1495
- }
1496
- return `?target <${escapedPredicate}> ${formatValue(condition)} .`;
1497
- }
1498
- }
1499
- function compileWhereClause(where, metadata) {
1500
- const conditions = [];
1501
- for (const [propertyName, condition] of Object.entries(where)) {
1502
- if (["id", "author", "timestamp"].includes(propertyName))
1503
- continue;
1504
- let predicate;
1505
- let resolveLanguage;
1506
- if (metadata) {
1507
- const propMeta = metadata.properties[propertyName];
1508
- if (propMeta) {
1509
- predicate = propMeta.predicate;
1510
- resolveLanguage = propMeta.resolveLanguage;
1511
- } else {
1512
- predicate = propertyName;
1513
- }
1514
- } else {
1515
- predicate = propertyName;
1516
- }
1517
- const cond = buildWhereCondition(predicate, condition, { resolveLanguage, varIndex: conditions.length });
1518
- if (cond) {
1519
- conditions.push(cond);
1520
- }
1521
- }
1522
- return conditions;
1523
- }
1524
1502
  function buildSHACL(subjectName, target, properties, allRelationsMeta, conformanceFilterFn) {
1525
1503
  const obj = target.prototype;
1526
1504
  let namespace = "ad4m://";
1527
- const relations = Object.fromEntries(Object.entries(allRelationsMeta).filter(([, r4]) => r4.kind === "hasMany" || r4.kind === "belongsToMany"));
1528
1505
  if (Object.keys(properties).length > 0) {
1529
1506
  const firstProp = properties[Object.keys(properties)[0]];
1530
1507
  if (firstProp.through) {
@@ -1533,8 +1510,8 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
1533
1510
  namespace = match[1];
1534
1511
  }
1535
1512
  }
1536
- } else if (Object.keys(relations).length > 0) {
1537
- const firstRel = relations[Object.keys(relations)[0]];
1513
+ } else if (Object.keys(allRelationsMeta).length > 0) {
1514
+ const firstRel = allRelationsMeta[Object.keys(allRelationsMeta)[0]];
1538
1515
  if (firstRel.predicate) {
1539
1516
  const match = firstRel.predicate.match(/^([^:]+:\/\/)/);
1540
1517
  if (match) {
@@ -1596,6 +1573,9 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
1596
1573
  if (propMeta.resolveLanguage) {
1597
1574
  propShape.resolveLanguage = propMeta.resolveLanguage;
1598
1575
  }
1576
+ if (propMeta.getter) {
1577
+ propShape.getter = propMeta.getter;
1578
+ }
1599
1579
  if (propMeta.prologSetter) {
1600
1580
  console.warn(`[SHACL Generation] Custom Prolog setter for property '${propName}' in class '${subjectName}' is not yet supported. The property will be created without setter actions. Consider using standard writable properties or provide explicit SHACL JSON.`);
1601
1581
  } else if (propMeta.writable && propMeta.through) {
@@ -1627,46 +1607,47 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
1627
1607
  }
1628
1608
  shape.addProperty(propShape);
1629
1609
  }
1630
- for (const relName in relations) {
1631
- const relMeta = relations[relName];
1632
- if (!relMeta.predicate)
1610
+ for (const relName in allRelationsMeta) {
1611
+ const relMeta = allRelationsMeta[relName];
1612
+ if (!relMeta.predicate && !relMeta.getter)
1633
1613
  continue;
1614
+ const synthesizedPath = relMeta.predicate || `ad4m://getter/${subjectName}/${relName}`;
1634
1615
  const relShape = {
1635
1616
  name: relName,
1636
- path: relMeta.predicate
1617
+ path: synthesizedPath
1637
1618
  };
1638
1619
  relShape.nodeKind = "IRI";
1620
+ relShape.relationKind = relMeta.kind;
1621
+ if (relMeta.kind === "hasOne" || relMeta.kind === "belongsToOne") {
1622
+ relShape.maxCount = 1;
1623
+ } else if (relMeta.maxCount !== void 0) {
1624
+ relShape.maxCount = relMeta.maxCount;
1625
+ }
1626
+ if (relMeta.filter === false) {
1627
+ relShape.filter = false;
1628
+ }
1639
1629
  if (relMeta.local !== void 0) {
1640
1630
  relShape.local = relMeta.local;
1641
1631
  }
1642
- relShape.adder = [{
1643
- action: "addLink",
1644
- source: "this",
1645
- predicate: relMeta.predicate,
1646
- target: "value",
1647
- ...relMeta.local && { local: true }
1648
- }];
1649
- relShape.remover = [{
1650
- action: "removeLink",
1651
- source: "this",
1652
- predicate: relMeta.predicate,
1653
- target: "value",
1654
- ...relMeta.local && { local: true }
1655
- }];
1632
+ if (relMeta.predicate) {
1633
+ relShape.adder = [{
1634
+ action: "addLink",
1635
+ source: "this",
1636
+ predicate: relMeta.predicate,
1637
+ target: "value",
1638
+ ...relMeta.local && { local: true }
1639
+ }];
1640
+ relShape.remover = [{
1641
+ action: "removeLink",
1642
+ source: "this",
1643
+ predicate: relMeta.predicate,
1644
+ target: "value",
1645
+ ...relMeta.local && { local: true }
1646
+ }];
1647
+ }
1656
1648
  if (relMeta.getter) {
1657
1649
  relShape.getter = relMeta.getter;
1658
- } else if (relMeta.where) {
1659
- try {
1660
- const TargetClass = relMeta.target?.();
1661
- const targetMetadata = TargetClass ? TargetClass.getModelMetadata?.() ?? null : null;
1662
- const conditions = compileWhereClause(relMeta.where, targetMetadata);
1663
- if (conditions.length > 0) {
1664
- const escapedPredicate = escapeQueryString(relMeta.predicate);
1665
- relShape.getter = `SELECT ?target WHERE { <Base> <${escapedPredicate}> ?target . ${conditions.join(" ")} }`;
1666
- }
1667
- } catch (e7) {
1668
- }
1669
- } else if (relMeta.target && relMeta.filter !== false) {
1650
+ } else if (relMeta.target && relMeta.filter !== false && relMeta.kind !== "belongsToOne" && relMeta.kind !== "belongsToMany") {
1670
1651
  const targetThunk = relMeta.target;
1671
1652
  const predicate = relMeta.predicate;
1672
1653
  let resolved = false;
@@ -1718,6 +1699,37 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
1718
1699
  if (targetSHACL?.shape?.nodeShapeUri) {
1719
1700
  relShape.class = targetSHACL.shape.nodeShapeUri;
1720
1701
  }
1702
+ if (targetSHACL?.name) {
1703
+ relShape.targetClassName = targetSHACL.name;
1704
+ } else {
1705
+ const targetProto = TargetClass.prototype;
1706
+ if (targetProto?.className) {
1707
+ relShape.targetClassName = targetProto.className;
1708
+ }
1709
+ }
1710
+ } catch (e7) {
1711
+ console.warn(`[shacl-gen] Failed to resolve target class for relation "${subjectName}.${relName}": ${e7 instanceof Error ? e7.message : String(e7)}`);
1712
+ }
1713
+ }
1714
+ if (relMeta.where) {
1715
+ relShape.whereFilter = relMeta.where;
1716
+ try {
1717
+ const TargetClass = relMeta.target?.();
1718
+ const targetMetadata = TargetClass ? TargetClass.getModelMetadata?.() ?? null : null;
1719
+ if (targetMetadata?.properties) {
1720
+ const predicates = {};
1721
+ for (const propName of Object.keys(relMeta.where)) {
1722
+ if (["id", "author", "timestamp"].includes(propName))
1723
+ continue;
1724
+ const propMeta = targetMetadata.properties[propName];
1725
+ if (propMeta?.predicate) {
1726
+ predicates[propName] = propMeta.predicate;
1727
+ }
1728
+ }
1729
+ if (Object.keys(predicates).length > 0) {
1730
+ relShape.wherePredicates = predicates;
1731
+ }
1732
+ }
1721
1733
  } catch (e7) {
1722
1734
  }
1723
1735
  }
@@ -1730,6 +1742,27 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
1730
1742
  name: subjectName
1731
1743
  };
1732
1744
  }
1745
+ function formatList(list) {
1746
+ if (!list?.length) {
1747
+ return "";
1748
+ }
1749
+ if (list.length === 1) {
1750
+ return list.toString();
1751
+ }
1752
+ if (list.length === 2) {
1753
+ return list.join(" and ");
1754
+ }
1755
+ return list.slice(0, -1).join(", ") + ", and " + list.slice(-1);
1756
+ }
1757
+ function capSentence(cap) {
1758
+ const can = cap.can.includes("*") ? ["READ", "WRITE", "UPDATE"] : cap.can;
1759
+ const domain = cap.with.domain === "*" ? "" : cap.with.domain;
1760
+ const pointers = cap.with.pointers.includes("*") ? ["all AD4M data"] : cap.with.pointers;
1761
+ return `${formatList(can)} your ${domain} actions, with access to ${formatList(pointers)}`;
1762
+ }
1763
+ function escapeQueryString(value) {
1764
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
1765
+ }
1733
1766
  var propertyRegistry = /* @__PURE__ */ new WeakMap();
1734
1767
  var relationRegistry = /* @__PURE__ */ new WeakMap();
1735
1768
  var propertiesMetadataCache = /* @__PURE__ */ new WeakMap();
@@ -2356,14 +2389,14 @@ var PerspectiveProxy = class {
2356
2389
  setCachedResult(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, query, result);
2357
2390
  return result;
2358
2391
  }
2359
- async modelQuery(className, queryJson, shapeJson) {
2360
- return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelQuery(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson, shapeJson);
2392
+ async modelQuery(className, queryJson) {
2393
+ return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelQuery(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson);
2361
2394
  }
2362
- async evaluateGetters(className, instanceIds, shapeJson, propertyNames) {
2363
- return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").evaluateGetters(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, instanceIds, shapeJson, propertyNames);
2395
+ async evaluateGetters(className, instanceIds, propertyNames) {
2396
+ return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").evaluateGetters(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, instanceIds, propertyNames);
2364
2397
  }
2365
- async modelSubscribe(className, queryJson, shapeJson) {
2366
- return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelSubscribe(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson, shapeJson);
2398
+ async modelSubscribe(className, queryJson) {
2399
+ return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelSubscribe(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson);
2367
2400
  }
2368
2401
  async add(link, status = "shared", batchId) {
2369
2402
  const result = await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").addLink(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, link, status, batchId);
@@ -3410,22 +3443,21 @@ var PerspectiveClient = class {
3410
3443
  }
3411
3444
  return __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.disposeQuery", { uuid, subscriptionId });
3412
3445
  }
3413
- async modelQuery(uuid, className, queryJson, shapeJson) {
3414
- const resultJson = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelQuery", { uuid, class_name: className, query_json: queryJson, shape_json: shapeJson });
3446
+ async modelQuery(uuid, className, queryJson) {
3447
+ const resultJson = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelQuery", { uuid, class_name: className, query_json: queryJson });
3415
3448
  return JSON.parse(resultJson);
3416
3449
  }
3417
- async evaluateGetters(uuid, className, instanceIds, shapeJson, propertyNames) {
3450
+ async evaluateGetters(uuid, className, instanceIds, propertyNames) {
3418
3451
  const resultJson = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.evaluateGetters", {
3419
3452
  uuid,
3420
3453
  class_name: className,
3421
3454
  instance_ids: instanceIds,
3422
- shape_json: shapeJson,
3423
3455
  ...propertyNames && { property_names: propertyNames }
3424
3456
  });
3425
3457
  return JSON.parse(resultJson);
3426
3458
  }
3427
- async modelSubscribe(uuid, className, queryJson, shapeJson) {
3428
- const response = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelSubscribe", { uuid, class_name: className, query_json: queryJson, shape_json: shapeJson });
3459
+ async modelSubscribe(uuid, className, queryJson) {
3460
+ const response = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelSubscribe", { uuid, class_name: className, query_json: queryJson });
3429
3461
  return {
3430
3462
  subscriptionId: response.subscription_id,
3431
3463
  result: JSON.parse(response.result)
@@ -9530,9 +9562,6 @@ var ModelQueryBuilder = class {
9530
9562
  this.modelClassName = className;
9531
9563
  return this;
9532
9564
  }
9533
- engine(_eng) {
9534
- return this;
9535
- }
9536
9565
  async get() {
9537
9566
  return await this.executeSparqlQuery();
9538
9567
  }
@@ -9553,8 +9582,8 @@ var ModelQueryBuilder = class {
9553
9582
  async subscribe(callback) {
9554
9583
  this.dispose();
9555
9584
  const ctor = this.ctor;
9556
- const { className, queryJson, shapeJson } = ctor.prepareModelQueryParams(this.queryParams, this.modelClassName);
9557
- const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson, shapeJson);
9585
+ const { className, queryJson } = ctor.prepareModelQueryParams(this.queryParams, this.modelClassName);
9586
+ const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson);
9558
9587
  const parseResults = (raw) => {
9559
9588
  return ctor.parseModelResult(this.perspective, raw, this.queryParams.include, this.queryParams.properties);
9560
9589
  };
@@ -9651,8 +9680,8 @@ var ModelQueryBuilder = class {
9651
9680
  async countSubscribe(callback) {
9652
9681
  this.dispose();
9653
9682
  const countParams = { ...this.queryParams, limit: 0 };
9654
- const { className, queryJson, shapeJson } = this.ctor.prepareModelQueryParams(countParams, this.modelClassName);
9655
- const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson, shapeJson);
9683
+ const { className, queryJson } = this.ctor.prepareModelQueryParams(countParams, this.modelClassName);
9684
+ const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson);
9656
9685
  const parseCount = (raw) => {
9657
9686
  const data = typeof raw === "string" ? JSON.parse(raw) : raw;
9658
9687
  return data.totalCount ?? 0;
@@ -9727,8 +9756,8 @@ var ModelQueryBuilder = class {
9727
9756
  const subscriptionParams = { ...this.queryParams || {} };
9728
9757
  delete subscriptionParams.limit;
9729
9758
  delete subscriptionParams.offset;
9730
- const { className, queryJson, shapeJson } = ctor.prepareModelQueryParams(subscriptionParams, this.modelClassName);
9731
- const { subscriptionId } = await this.perspective.modelSubscribe(className, queryJson, shapeJson);
9759
+ const { className, queryJson } = ctor.prepareModelQueryParams(subscriptionParams, this.modelClassName);
9760
+ const { subscriptionId } = await this.perspective.modelSubscribe(className, queryJson);
9732
9761
  const paginatedQuery = {
9733
9762
  ...this.queryParams || {},
9734
9763
  limit: pageSize,
@@ -9820,34 +9849,6 @@ function defaultFileDecode(resolved) {
9820
9849
  }
9821
9850
  return resolved;
9822
9851
  }
9823
- function enrichShapeForIncludes(metadata, include, allRelMeta) {
9824
- for (const [relName, includeVal] of Object.entries(include)) {
9825
- if (!includeVal)
9826
- continue;
9827
- const meta = allRelMeta[relName];
9828
- if (!meta?.target)
9829
- continue;
9830
- const TargetClass = meta.target();
9831
- const targetMeta = JSON.parse(JSON.stringify(TargetClass.getModelMetadata()));
9832
- if (!metadata.relations[relName]) {
9833
- metadata.relations[relName] = {
9834
- name: relName,
9835
- predicate: meta.predicate,
9836
- direction: meta.kind === "belongsToMany" || meta.kind === "belongsToOne" ? "reverse" : "forward"
9837
- };
9838
- }
9839
- const rel = metadata.relations[relName];
9840
- rel.kind = meta.kind;
9841
- rel.maxCount = meta.maxCount;
9842
- rel.targetShape = targetMeta;
9843
- rel.targetClassName = targetMeta.className;
9844
- const nested = typeof includeVal === "object" && includeVal !== null ? includeVal.include : void 0;
9845
- if (nested) {
9846
- const targetRelMeta = getRelationsMetadata(TargetClass);
9847
- enrichShapeForIncludes(targetMeta, nested, targetRelMeta);
9848
- }
9849
- }
9850
- }
9851
9852
  function jsonToModelInstance(ModelClass, perspective, json, include, properties) {
9852
9853
  const instance = new ModelClass(perspective, json.id || json.baseExpression);
9853
9854
  if (properties) {
@@ -10230,12 +10231,12 @@ var Ad4mModel = class {
10230
10231
  const allRelMeta = getRelationsMetadata(this);
10231
10232
  for (const [, proj] of Object.entries(projections)) {
10232
10233
  const relMeta = allRelMeta[proj.from];
10233
- if (!proj.targetShape && relMeta?.target) {
10234
+ if (!proj.targetClassName && relMeta?.target) {
10234
10235
  try {
10235
10236
  const TargetClass = relMeta.target();
10236
10237
  const targetMeta = TargetClass.getModelMetadata?.();
10237
- if (targetMeta) {
10238
- proj.targetShape = targetMeta;
10238
+ if (targetMeta?.className) {
10239
+ proj.targetClassName = targetMeta.className;
10239
10240
  }
10240
10241
  } catch (e7) {
10241
10242
  console.debug(`prepareModelQueryParams: target class unavailable for projection:`, e7);
@@ -10257,56 +10258,9 @@ var Ad4mModel = class {
10257
10258
  if (query.count !== void 0)
10258
10259
  queryInput.count = query.count;
10259
10260
  queryInput.deepQuery = query.deepQuery ?? true;
10260
- if (queryInput.include) {
10261
- const allRelMeta = getRelationsMetadata(this);
10262
- enrichShapeForIncludes(metadata, queryInput.include, allRelMeta);
10263
- }
10264
- {
10265
- const allRelMeta = getRelationsMetadata(this);
10266
- for (const [relName, relMeta] of Object.entries(metadata.relations)) {
10267
- const rel = relMeta;
10268
- if (rel.getter || rel.direction === "reverse" || rel.filter === false)
10269
- continue;
10270
- const meta = allRelMeta[relName];
10271
- if (!meta?.target)
10272
- continue;
10273
- try {
10274
- const TargetClass = meta.target();
10275
- const filter = buildConformanceFilter(meta.predicate, TargetClass);
10276
- if (filter) {
10277
- rel.getter = filter.getter;
10278
- }
10279
- if (rel.where) {
10280
- try {
10281
- const targetMetadata = TargetClass.getModelMetadata?.() ?? null;
10282
- if (targetMetadata) {
10283
- const predicates = {};
10284
- for (const propName of Object.keys(rel.where)) {
10285
- if (["id", "author", "timestamp"].includes(propName))
10286
- continue;
10287
- const propMeta = targetMetadata.properties[propName];
10288
- if (propMeta?.predicate) {
10289
- predicates[propName] = propMeta.predicate;
10290
- }
10291
- }
10292
- if (Object.keys(predicates).length > 0) {
10293
- rel.whereFilter = rel.where;
10294
- rel.wherePredicates = predicates;
10295
- }
10296
- }
10297
- } catch (e7) {
10298
- console.debug(`prepareModelQueryParams: target metadata unavailable for relation '${relName}':`, e7);
10299
- }
10300
- }
10301
- } catch (e7) {
10302
- console.debug(`prepareModelQueryParams: target class unavailable for relation '${relName}':`, e7);
10303
- }
10304
- }
10305
- }
10306
10261
  return {
10307
10262
  className,
10308
10263
  queryJson: JSON.stringify(queryInput),
10309
- shapeJson: JSON.stringify(metadata),
10310
10264
  metadata
10311
10265
  };
10312
10266
  }
@@ -10349,8 +10303,8 @@ var Ad4mModel = class {
10349
10303
  }));
10350
10304
  }
10351
10305
  static async executeModelQuery(perspective, query = {}, classNameOverride) {
10352
- const { className, queryJson, shapeJson } = this.prepareModelQueryParams(query, classNameOverride);
10353
- const result = await perspective.modelQuery(className, queryJson, shapeJson);
10306
+ const { className, queryJson } = this.prepareModelQueryParams(query, classNameOverride);
10307
+ const result = await perspective.modelQuery(className, queryJson);
10354
10308
  const instances = result.instances.map((json) => {
10355
10309
  return jsonToModelInstance(this, perspective, json, query.include, query.properties);
10356
10310
  });
@@ -10364,28 +10318,30 @@ var Ad4mModel = class {
10364
10318
  totalCount: result.totalCount
10365
10319
  };
10366
10320
  }
10367
- static async findAll(perspective, query = {}, _engine) {
10368
- if (query.properties && query.properties.length === 0) {
10321
+ static async findAll(perspective, query) {
10322
+ const q = query ?? {};
10323
+ if (q.properties && q.properties.length === 0) {
10369
10324
  throw new Error("properties[] must not be empty \u2014 omit the field to return all properties, or specify at least one field name");
10370
10325
  }
10371
- const { results } = await this.executeModelQuery(perspective, query);
10326
+ const { results } = await this.executeModelQuery(perspective, q);
10372
10327
  return results;
10373
10328
  }
10374
- static async findOne(perspective, query = {}, _engine) {
10375
- const limitedQuery = { ...query, limit: 1 };
10329
+ static async findOne(perspective, query) {
10330
+ const limitedQuery = { ...query ?? {}, limit: 1 };
10376
10331
  const results = await this.findAll(perspective, limitedQuery);
10377
10332
  return results[0] ?? null;
10378
10333
  }
10379
- static async findAllAndCount(perspective, query = {}, _engine) {
10380
- return await this.executeModelQuery(perspective, query);
10334
+ static async findAllAndCount(perspective, query) {
10335
+ const out = await this.executeModelQuery(perspective, query ?? {});
10336
+ return out;
10381
10337
  }
10382
- static async paginate(perspective, pageSize, pageNumber, query, _engine) {
10383
- const paginationQuery = { ...query || {}, limit: pageSize, offset: pageSize * (pageNumber - 1), count: true };
10338
+ static async paginate(perspective, pageSize, pageNumber, query) {
10339
+ const paginationQuery = { ...query ?? {}, limit: pageSize, offset: pageSize * (pageNumber - 1), count: true };
10384
10340
  const { results, totalCount } = await this.executeModelQuery(perspective, paginationQuery);
10385
10341
  return { results, totalCount, pageSize, pageNumber };
10386
10342
  }
10387
- static async count(perspective, query = {}) {
10388
- const { totalCount } = await this.executeModelQuery(perspective, { ...query, limit: 0 });
10343
+ static async count(perspective, query) {
10344
+ const { totalCount } = await this.executeModelQuery(perspective, { ...query ?? {}, limit: 0 });
10389
10345
  return totalCount;
10390
10346
  }
10391
10347
  async setProperty(key, value, batchId) {
@@ -10581,26 +10537,8 @@ var Ad4mModel = class {
10581
10537
  if (instances.length === 0)
10582
10538
  return;
10583
10539
  const metadata = this.getModelMetadata();
10584
- const allRelMeta = getRelationsMetadata(this);
10585
- for (const [relName, relMeta] of Object.entries(metadata.relations)) {
10586
- const rel = relMeta;
10587
- if (rel.getter || rel.direction === "reverse" || rel.filter === false)
10588
- continue;
10589
- const meta = allRelMeta[relName];
10590
- if (!meta?.target)
10591
- continue;
10592
- try {
10593
- const TargetClass = meta.target();
10594
- const filter = buildConformanceFilter(meta.predicate, TargetClass);
10595
- if (filter)
10596
- rel.getter = filter.getter;
10597
- } catch (e7) {
10598
- console.debug(`evaluateGetters: target class unavailable for relation '${relName}':`, e7);
10599
- }
10600
- }
10601
- const shapeJson = JSON.stringify(metadata);
10602
10540
  const instanceIds = instances.map((inst) => inst.id || inst._baseExpression);
10603
- const result = await perspective.evaluateGetters(metadata.className, instanceIds, shapeJson, propertyNames);
10541
+ const result = await perspective.evaluateGetters(metadata.className, instanceIds, propertyNames);
10604
10542
  const evaluatedPropertyNames = [];
10605
10543
  for (const [propName, propMeta] of Object.entries(metadata.properties)) {
10606
10544
  if (propMeta.getter) {
@@ -10734,7 +10672,7 @@ var Ad4mModel = class {
10734
10672
  return result;
10735
10673
  }
10736
10674
  static query(perspective, query) {
10737
- return new ModelQueryBuilder(perspective, this, query);
10675
+ return new ModelQueryBuilder(perspective, this, query ?? {});
10738
10676
  }
10739
10677
  static fromJSONSchema(schema, options) {
10740
10678
  return buildModelFromJSONSchema(this, schema, options);
@@ -11246,11 +11184,10 @@ var Ad4mConnect = class extends EventTarget {
11246
11184
  setLocal("ad4m-last-host", JSON.stringify({ id: host.id, url: host.url, name: host.name, location: host.location }));
11247
11185
  }
11248
11186
  initializeEmbeddedMode() {
11249
- var _a;
11250
11187
  console.log("[Ad4m Connect] Running in embedded mode - waiting for AD4M config from parent");
11251
11188
  window.addEventListener("message", (event) => __async(this, null, function* () {
11252
- var _a2;
11253
- if (((_a2 = event.data) == null ? void 0 : _a2.type) === "AD4M_CONFIG") {
11189
+ var _a;
11190
+ if (((_a = event.data) == null ? void 0 : _a.type) === "AD4M_CONFIG") {
11254
11191
  if (event.source !== window.parent) {
11255
11192
  console.warn("[Ad4m Connect] Rejected AD4M_CONFIG from invalid source (not parent window)");
11256
11193
  return;
@@ -11287,8 +11224,8 @@ var Ad4mConnect = class extends EventTarget {
11287
11224
  if (!event.origin || event.origin === "null") {
11288
11225
  throw new Error("AD4M proxy mode requires a non-opaque parent origin. Ensure the host iframe is not sandboxed without allow-same-origin.");
11289
11226
  }
11290
- const parentOrigin2 = event.origin;
11291
- const wsImpl = (url) => new PostMessageWebSocket(url, parentOrigin2);
11227
+ const parentOrigin = event.origin;
11228
+ const wsImpl = (url) => new PostMessageWebSocket(url, parentOrigin);
11292
11229
  this.notifyConnectionChange("connecting");
11293
11230
  this.ad4mClient = new Ad4mClient(
11294
11231
  "http://proxy",
@@ -11339,14 +11276,7 @@ var Ad4mConnect = class extends EventTarget {
11339
11276
  }
11340
11277
  }));
11341
11278
  console.log("[Ad4m Connect] Requesting AD4M config from parent window");
11342
- let parentOrigin = "*";
11343
- const referrerOrigin = document.referrer ? new URL(document.referrer).origin : null;
11344
- if (referrerOrigin && ((_a = this.options.allowedOrigins) == null ? void 0 : _a.includes(referrerOrigin))) {
11345
- parentOrigin = referrerOrigin;
11346
- } else if (this.options.allowedOrigins && this.options.allowedOrigins.length === 1) {
11347
- parentOrigin = this.options.allowedOrigins[0];
11348
- }
11349
- window.parent.postMessage({ type: "REQUEST_AD4M_CONFIG" }, parentOrigin);
11279
+ window.parent.postMessage({ type: "REQUEST_AD4M_CONFIG" }, "*");
11350
11280
  }
11351
11281
  buildAppInfo() {
11352
11282
  return {