@coasys/ad4m-connect 0.13.0-test-8 → 0.13.0-test-9

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/core.d.ts CHANGED
@@ -51,6 +51,16 @@ export default class Ad4mConnect extends EventTarget {
51
51
  verifyEmailCode(email: string, code: string): Promise<boolean>;
52
52
  loginWithPassword(email: string, password: string): Promise<boolean>;
53
53
  createAccount(email: string, password: string): Promise<boolean>;
54
+ /**
55
+ * Connect to a remote hosted node as a guest without any UI interaction.
56
+ * Generates a persistent random identity stored in localStorage so that
57
+ * refreshing the page reuses the same guest account.
58
+ *
59
+ * Tries loginUser first (returning visitor); falls back to createUser +
60
+ * loginUser (first visit). No email verification required — password-based
61
+ * accounts on multi-user executors skip the email code step entirely.
62
+ */
63
+ connectAsGuest(hostUrl: string): Promise<Ad4mClient>;
54
64
  private resolveEmbedded;
55
65
  private rejectEmbedded;
56
66
  private notifyConnectionChange;
package/dist/core.js CHANGED
@@ -39,7 +39,7 @@ var __async = (__this, __arguments, generator) => {
39
39
  };
40
40
 
41
41
  // ../package.json
42
- var version = "0.13.0-test-8";
42
+ var version = "0.13.0-test-9";
43
43
 
44
44
  // src/utils.ts
45
45
  function isEmbedded() {
@@ -1599,7 +1599,7 @@ var SHACLShape = class {
1599
1599
  return shape;
1600
1600
  }
1601
1601
  };
1602
- function buildSHACL(subjectName, target, properties, allRelationsMeta, conformanceFilterFn) {
1602
+ function buildSHACL(subjectName, target, properties, allRelationsMeta, conformanceFilterFn, seedCache) {
1603
1603
  const obj = target.prototype;
1604
1604
  let namespace = "ad4m://";
1605
1605
  if (Object.keys(properties).length > 0) {
@@ -1622,6 +1622,9 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
1622
1622
  const shapeUri = `${namespace}${subjectName}Shape`;
1623
1623
  const targetClass = `${namespace}${subjectName}`;
1624
1624
  const shape = new SHACLShape(shapeUri, targetClass);
1625
+ if (seedCache) {
1626
+ seedCache({ shape, name: subjectName });
1627
+ }
1625
1628
  const parentCtor = Object.getPrototypeOf(target);
1626
1629
  if (parentCtor && typeof parentCtor.generateSHACL === "function") {
1627
1630
  const parentSHACL = parentCtor.generateSHACL();
@@ -1895,7 +1898,16 @@ function getMemoizedSHACL(target, compute) {
1895
1898
  const cached = shaclCache.get(target);
1896
1899
  if (cached)
1897
1900
  return cached;
1898
- const result = compute();
1901
+ const seed = (partial) => {
1902
+ shaclCache.set(target, partial);
1903
+ };
1904
+ let result;
1905
+ try {
1906
+ result = compute(seed);
1907
+ } catch (e) {
1908
+ shaclCache.delete(target);
1909
+ throw e;
1910
+ }
1899
1911
  shaclCache.set(target, result);
1900
1912
  return result;
1901
1913
  }
@@ -1951,7 +1963,7 @@ function Model$1(opts) {
1951
1963
  return buildSDNA(opts.name, target.prototype, getPropertiesMetadata(target), getRelationsMetadata(target));
1952
1964
  };
1953
1965
  target.generateSHACL = function() {
1954
- return getMemoizedSHACL(target, () => buildSHACL(opts.name, target, getPropertiesMetadata(target), getRelationsMetadata(target), buildConformanceFilter));
1966
+ return getMemoizedSHACL(target, (seed) => buildSHACL(opts.name, target, getPropertiesMetadata(target), getRelationsMetadata(target), buildConformanceFilter, seed));
1955
1967
  };
1956
1968
  Object.defineProperty(target, "type", { configurable: true });
1957
1969
  };
@@ -2822,10 +2834,15 @@ var PerspectiveProxy = class {
2822
2834
  predicate: "sh://property"
2823
2835
  }));
2824
2836
  const sourceUris = [shapeUri, ...propertyLinks.map((l) => l.data.target)];
2837
+ const linksByUri = await Promise.all(sourceUris.map((uri) => this.get(new LinkQuery({ source: uri }))));
2838
+ const seenLinks = /* @__PURE__ */ new Set();
2825
2839
  const allLinks = [];
2826
- for (const uri of sourceUris) {
2827
- const links = await this.get(new LinkQuery({ source: uri }));
2840
+ for (const links of linksByUri) {
2828
2841
  for (const l of links) {
2842
+ const key = `${l.data.source} ${l.data.predicate} ${l.data.target}`;
2843
+ if (seenLinks.has(key))
2844
+ continue;
2845
+ seenLinks.add(key);
2829
2846
  allLinks.push({
2830
2847
  source: l.data.source,
2831
2848
  predicate: l.data.predicate,
@@ -2836,22 +2853,37 @@ var PerspectiveProxy = class {
2836
2853
  const shapeLinks = allLinks;
2837
2854
  return SHACLShape.fromLinks(shapeLinks, shapeUri);
2838
2855
  }
2839
- async getAllShacl() {
2856
+ async getShaclNames() {
2840
2857
  const nameLinks = await this.get(new LinkQuery({
2841
2858
  source: "ad4m://self",
2842
2859
  predicate: "ad4m://has_shacl"
2843
2860
  }));
2844
- const shapes = [];
2845
- for (const nameLink of nameLinks) {
2846
- const nameUrl = nameLink.data.target;
2847
- const name = Literal.fromUrl(nameUrl).get();
2848
- const shapeName = name.replace("shacl://", "");
2849
- const shape = await this.getShacl(shapeName);
2850
- if (shape) {
2851
- shapes.push({ name: shapeName, shape });
2852
- }
2861
+ const names = nameLinks.map((nameLink) => {
2862
+ const name = Literal.fromUrl(nameLink.data.target).get();
2863
+ return name.replace("shacl://", "");
2864
+ });
2865
+ return [...new Set(names)];
2866
+ }
2867
+ async getShaclTargetClass(name) {
2868
+ const nameMapping = Literal.fromUrl(`literal:string:shacl://${name}`);
2869
+ const shapeUriLinks = await this.get(new LinkQuery({
2870
+ source: nameMapping.toUrl(),
2871
+ predicate: "ad4m://shacl_shape_uri"
2872
+ }));
2873
+ if (shapeUriLinks.length === 0) {
2874
+ return void 0;
2853
2875
  }
2854
- return shapes;
2876
+ const shapeUri = shapeUriLinks[0].data.target;
2877
+ const shapeOwnLinks = await this.get(new LinkQuery({ source: shapeUri }));
2878
+ return shapeOwnLinks.find((l) => l.data.predicate === "sh://targetClass")?.data.target;
2879
+ }
2880
+ async getAllShacl() {
2881
+ const shapeNames = await this.getShaclNames();
2882
+ const results = await Promise.all(shapeNames.map(async (shapeName) => {
2883
+ const shape = await this.getShacl(shapeName);
2884
+ return shape ? { name: shapeName, shape } : null;
2885
+ }));
2886
+ return results.filter((s) => s !== null);
2855
2887
  }
2856
2888
  async addFlow(name, flow) {
2857
2889
  const flowLinks = flow.toLinks();
@@ -3939,12 +3971,12 @@ var AgentClient = class {
3939
3971
  }
3940
3972
  }
3941
3973
  const promise = (async () => {
3942
- const persisted = await __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").get(did);
3943
- if (persisted) {
3944
- return persisted;
3974
+ const entry = await __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").get(did);
3975
+ if (entry?.agent && now - (entry.ts ?? 0) < AgentClient.REMOTE_AGENT_TTL_L2_MS) {
3976
+ return entry.agent;
3945
3977
  }
3946
3978
  const result = await __classPrivateFieldGet$7(this, _AgentClient_apiClient, "f").call("agent.byDid", { did });
3947
- __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").put(did, result);
3979
+ __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").put(did, { agent: result, ts: Date.now() });
3948
3980
  return result;
3949
3981
  })();
3950
3982
  __classPrivateFieldGet$7(this, _AgentClient_memCache, "f").set(did, { promise, ts: now });
@@ -3979,7 +4011,7 @@ var AgentClient = class {
3979
4011
  agent.directMessageLanguage = a.directMessageLanguage;
3980
4012
  if (agent.did) {
3981
4013
  __classPrivateFieldGet$7(this, _AgentClient_memCache, "f").set(agent.did, { promise: Promise.resolve(agent), ts: Date.now() });
3982
- __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").put(agent.did, agent);
4014
+ __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").put(agent.did, { agent, ts: Date.now() });
3983
4015
  }
3984
4016
  return agent;
3985
4017
  }
@@ -4007,7 +4039,7 @@ var AgentClient = class {
4007
4039
  agent.directMessageLanguage = a.directMessageLanguage;
4008
4040
  if (agent.did) {
4009
4041
  __classPrivateFieldGet$7(this, _AgentClient_memCache, "f").set(agent.did, { promise: Promise.resolve(agent), ts: Date.now() });
4010
- __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").put(agent.did, agent);
4042
+ __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").put(agent.did, { agent, ts: Date.now() });
4011
4043
  }
4012
4044
  return agent;
4013
4045
  }
@@ -4038,7 +4070,7 @@ var AgentClient = class {
4038
4070
  promise: Promise.resolve(agent),
4039
4071
  ts: Date.now()
4040
4072
  });
4041
- __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").put(agent.did, agent);
4073
+ __classPrivateFieldGet$7(this, _AgentClient_persistent, "f").put(agent.did, { agent, ts: Date.now() });
4042
4074
  }
4043
4075
  __classPrivateFieldGet$7(this, _AgentClient_updatedCallbacks, "f").forEach((cb) => cb(agent));
4044
4076
  }
@@ -4139,6 +4171,7 @@ var AgentClient = class {
4139
4171
  };
4140
4172
  _AgentClient_apiClient = /* @__PURE__ */ new WeakMap(), _AgentClient_baseUrl = /* @__PURE__ */ new WeakMap(), _AgentClient_token = /* @__PURE__ */ new WeakMap(), _AgentClient_appsChangedCallback = /* @__PURE__ */ new WeakMap(), _AgentClient_updatedCallbacks = /* @__PURE__ */ new WeakMap(), _AgentClient_agentStatusChangedCallbacks = /* @__PURE__ */ new WeakMap(), _AgentClient_hostingUserInfoChangedCallbacks = /* @__PURE__ */ new WeakMap(), _AgentClient_computeLogUpdatedCallbacks = /* @__PURE__ */ new WeakMap(), _AgentClient_unsubscribers = /* @__PURE__ */ new WeakMap(), _AgentClient_memCache = /* @__PURE__ */ new WeakMap(), _AgentClient_persistent = /* @__PURE__ */ new WeakMap(), _AgentClient_selfDid = /* @__PURE__ */ new WeakMap();
4141
4173
  AgentClient.REMOTE_AGENT_TTL_MS = 5 * 6e4;
4174
+ AgentClient.REMOTE_AGENT_TTL_L2_MS = 5 * 6e4;
4142
4175
  var __classPrivateFieldSet$6 = function(receiver, state, value, kind, f) {
4143
4176
  if (kind === "m")
4144
4177
  throw new TypeError("Private method is not writable");
@@ -9297,6 +9330,9 @@ function hasJsOnlyWhereFilters(metadata, allRelationsMetadata, where) {
9297
9330
  for (const [propertyName, condition] of Object.entries(where)) {
9298
9331
  if (propertyName === "base" || propertyName === "id")
9299
9332
  continue;
9333
+ if (propertyName === "OR" || propertyName === "AND" || propertyName === "NOT") {
9334
+ return true;
9335
+ }
9300
9336
  if (propertyName === "author" || propertyName === "timestamp")
9301
9337
  return true;
9302
9338
  const propMeta = metadata.properties[propertyName];
@@ -9484,6 +9520,9 @@ function buildSPARQLWhereFilters(metadata, _allRelationsMetadata, where) {
9484
9520
  const joins = [];
9485
9521
  const filters = [];
9486
9522
  for (const [propertyName, condition] of Object.entries(where)) {
9523
+ if (propertyName === "OR" || propertyName === "AND" || propertyName === "NOT") {
9524
+ continue;
9525
+ }
9487
9526
  if (propertyName === "base" || propertyName === "id") {
9488
9527
  if (Array.isArray(condition)) {
9489
9528
  const formatted = condition.map((v) => iri(v)).join(", ");
@@ -10958,6 +10997,20 @@ var DEFAULT_PORT = 12e3;
10958
10997
  var DEFAULT_INDEX_URL = "https://hosting.ad4m.dev";
10959
10998
  var CREDIT_POLL_INTERVAL_MS = 6e4;
10960
10999
  var DEFAULT_LOW_CREDIT_THRESHOLD = 10;
11000
+ function originAllowed(allowedOrigins, origin) {
11001
+ return allowedOrigins.some((pattern) => {
11002
+ if (pattern === "http://localhost:*" || pattern === "https://localhost:*") {
11003
+ try {
11004
+ const u = new URL(origin);
11005
+ const scheme = pattern.startsWith("https") ? "https:" : "http:";
11006
+ return u.hostname === "localhost" && u.protocol === scheme;
11007
+ } catch (e) {
11008
+ return false;
11009
+ }
11010
+ }
11011
+ return pattern === origin;
11012
+ });
11013
+ }
10961
11014
  var Ad4mConnect = class extends EventTarget {
10962
11015
  constructor(options) {
10963
11016
  var _a;
@@ -11223,13 +11276,13 @@ var Ad4mConnect = class extends EventTarget {
11223
11276
  this.rejectEmbedded(new Error("proxy mode requires allowedOrigins"));
11224
11277
  return;
11225
11278
  }
11226
- if (!event.origin || !this.options.allowedOrigins.includes(event.origin)) {
11279
+ if (!event.origin || !originAllowed(this.options.allowedOrigins, event.origin)) {
11227
11280
  console.warn("[Ad4m Connect] Rejected AD4M_CONFIG from unauthorized origin:", event.origin);
11228
11281
  this.rejectEmbedded(new Error(`Unauthorized origin: ${event.origin}`));
11229
11282
  return;
11230
11283
  }
11231
11284
  } else if (this.options.allowedOrigins && this.options.allowedOrigins.length > 0) {
11232
- if (!event.origin || !this.options.allowedOrigins.includes(event.origin)) {
11285
+ if (!event.origin || !originAllowed(this.options.allowedOrigins, event.origin)) {
11233
11286
  console.warn("[Ad4m Connect] Rejected AD4M_CONFIG from unauthorized origin:", event.origin);
11234
11287
  this.rejectEmbedded(new Error(`Unauthorized origin: ${event.origin}`));
11235
11288
  return;
@@ -11442,6 +11495,48 @@ var Ad4mConnect = class extends EventTarget {
11442
11495
  }
11443
11496
  });
11444
11497
  }
11498
+ connectAsGuest(hostUrl) {
11499
+ return __async(this, null, function* () {
11500
+ this.url = hostUrl;
11501
+ setLocal("ad4m-url", hostUrl);
11502
+ const normalizedHost = hostUrl.replace(/\/+$/, "").toLowerCase();
11503
+ const GUEST_EMAIL_KEY = `ad4m-guest-email-${normalizedHost}`;
11504
+ const GUEST_PASS_KEY = `ad4m-guest-pass-${normalizedHost}`;
11505
+ const storedEmail = getLocal(GUEST_EMAIL_KEY);
11506
+ const storedPassword = getLocal(GUEST_PASS_KEY);
11507
+ let email;
11508
+ let password;
11509
+ if (storedEmail && storedPassword) {
11510
+ email = storedEmail;
11511
+ password = storedPassword;
11512
+ } else {
11513
+ email = `guest-${crypto.randomUUID()}@flux.demo`;
11514
+ password = crypto.randomUUID();
11515
+ }
11516
+ const isReturningGuest = !!(storedEmail && storedPassword);
11517
+ const token = yield this.withTempClient(hostUrl, (client) => __async(this, null, function* () {
11518
+ if (isReturningGuest) {
11519
+ return yield client.agent.loginUser(email, password);
11520
+ } else {
11521
+ const result = yield client.agent.createUser(email, password);
11522
+ if (!result.success)
11523
+ throw new Error(result.error || "Failed to create guest account");
11524
+ const newToken = yield client.agent.loginUser(email, password);
11525
+ setLocal(GUEST_EMAIL_KEY, email);
11526
+ setLocal(GUEST_PASS_KEY, password);
11527
+ return newToken;
11528
+ }
11529
+ }));
11530
+ this.token = token;
11531
+ setLocal("ad4m-token", token);
11532
+ this.ad4mClient = this.buildClient();
11533
+ yield this.checkAuth();
11534
+ if (this.authState !== "authenticated") {
11535
+ throw new Error(`Guest authentication failed: auth state is "${this.authState}"`);
11536
+ }
11537
+ return this.ad4mClient;
11538
+ });
11539
+ }
11445
11540
  resolveEmbedded(client) {
11446
11541
  if (this.embeddedResolve) {
11447
11542
  this.embeddedResolve(client);