s3db.js 4.1.1 → 4.1.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/s3db.iife.js CHANGED
@@ -9598,20 +9598,13 @@ ${JSON.stringify(validation, null, 2)}`
9598
9598
  * @returns {string} SHA256 hash of the schema definition
9599
9599
  */
9600
9600
  getDefinitionHash() {
9601
- const exportedSchema = this.schema.export();
9602
- const stableSchema = {
9603
- ...exportedSchema,
9604
- attributes: { ...exportedSchema.attributes }
9605
- };
9601
+ const attributes = this.schema.export().attributes;
9602
+ const stableAttributes = { ...attributes };
9606
9603
  if (this.options.timestamps) {
9607
- delete stableSchema.attributes.createdAt;
9608
- delete stableSchema.attributes.updatedAt;
9609
- if (stableSchema.options && stableSchema.options.partitions) {
9610
- delete stableSchema.options.partitions.byCreatedDate;
9611
- delete stableSchema.options.partitions.byUpdatedDate;
9612
- }
9604
+ delete stableAttributes.createdAt;
9605
+ delete stableAttributes.updatedAt;
9613
9606
  }
9614
- const stableString = jsonStableStringify(stableSchema);
9607
+ const stableString = jsonStableStringify(stableAttributes);
9615
9608
  return `sha256:${crypto.createHash("sha256").update(stableString).digest("hex")}`;
9616
9609
  }
9617
9610
  /**
@@ -9805,7 +9798,7 @@ ${JSON.stringify(validation, null, 2)}`
9805
9798
  this.version = "1";
9806
9799
  this.s3dbVersion = (() => {
9807
9800
  try {
9808
- return true ? "4.1.0" : "latest";
9801
+ return true ? "4.1.2" : "latest";
9809
9802
  } catch (e) {
9810
9803
  return "latest";
9811
9804
  }
@@ -9917,10 +9910,21 @@ ${JSON.stringify(validation, null, 2)}`
9917
9910
  /**
9918
9911
  * Generate a consistent hash for a resource definition
9919
9912
  * @param {Object} definition - Resource definition to hash
9913
+ * @param {string} behavior - Resource behavior
9920
9914
  * @returns {string} SHA256 hash
9921
9915
  */
9922
- generateDefinitionHash(definition) {
9923
- const stableString = jsonStableStringify(definition);
9916
+ generateDefinitionHash(definition, behavior = void 0) {
9917
+ const attributes = definition.attributes;
9918
+ const stableAttributes = { ...attributes };
9919
+ if (definition.options?.timestamps) {
9920
+ delete stableAttributes.createdAt;
9921
+ delete stableAttributes.updatedAt;
9922
+ }
9923
+ const hashObj = {
9924
+ attributes: stableAttributes,
9925
+ behavior: behavior || definition.behavior || "user-management"
9926
+ };
9927
+ const stableString = jsonStableStringify(hashObj);
9924
9928
  return `sha256:${crypto.createHash("sha256").update(stableString).digest("hex")}`;
9925
9929
  }
9926
9930
  /**
@@ -10007,6 +10011,73 @@ ${JSON.stringify(validation, null, 2)}`
10007
10011
  resources: {}
10008
10012
  };
10009
10013
  }
10014
+ /**
10015
+ * Check if a resource exists by name
10016
+ * @param {string} name - Resource name
10017
+ * @returns {boolean} True if resource exists, false otherwise
10018
+ */
10019
+ resourceExists(name) {
10020
+ return !!this.resources[name];
10021
+ }
10022
+ /**
10023
+ * Check if a resource exists with the same definition hash
10024
+ * @param {string} name - Resource name
10025
+ * @param {Object} attributes - Resource attributes
10026
+ * @param {Object} options - Resource options
10027
+ * @param {string} behavior - Resource behavior
10028
+ * @returns {Object} Object with exists flag and hash information
10029
+ */
10030
+ resourceExistsWithSameHash({ name, attributes, options = {}, behavior = "user-management" }) {
10031
+ if (!this.resources[name]) {
10032
+ return { exists: false, sameHash: false, hash: null };
10033
+ }
10034
+ const tempResource = new Resource({
10035
+ name,
10036
+ attributes,
10037
+ behavior,
10038
+ observers: [],
10039
+ client: this.client,
10040
+ version: "temp",
10041
+ options: {
10042
+ cache: this.cache,
10043
+ ...options
10044
+ }
10045
+ });
10046
+ const newHash = this.generateDefinitionHash(tempResource.export(), behavior);
10047
+ const existingHash = this.generateDefinitionHash(this.resources[name].export(), this.resources[name].behavior);
10048
+ return {
10049
+ exists: true,
10050
+ sameHash: newHash === existingHash,
10051
+ hash: newHash,
10052
+ existingHash
10053
+ };
10054
+ }
10055
+ /**
10056
+ * Create a resource only if it doesn't exist with the same definition hash
10057
+ * @param {Object} params - Resource parameters
10058
+ * @param {string} params.name - Resource name
10059
+ * @param {Object} params.attributes - Resource attributes
10060
+ * @param {Object} params.options - Resource options
10061
+ * @param {string} params.behavior - Resource behavior
10062
+ * @returns {Object} Object with resource and created flag
10063
+ */
10064
+ async createResourceIfNotExists({ name, attributes, options = {}, behavior = "user-management" }) {
10065
+ const alreadyExists = !!this.resources[name];
10066
+ const hashCheck = this.resourceExistsWithSameHash({ name, attributes, options, behavior });
10067
+ if (hashCheck.exists && hashCheck.sameHash) {
10068
+ return {
10069
+ resource: this.resources[name],
10070
+ created: false,
10071
+ reason: "Resource already exists with same definition hash"
10072
+ };
10073
+ }
10074
+ const resource = await this.createResource({ name, attributes, options, behavior });
10075
+ return {
10076
+ resource,
10077
+ created: !alreadyExists,
10078
+ reason: alreadyExists ? "Resource updated with new definition" : "New resource created"
10079
+ };
10080
+ }
10010
10081
  async createResource({ name, attributes, options = {}, behavior = "user-management" }) {
10011
10082
  if (this.resources[name]) {
10012
10083
  const existingResource = this.resources[name];
@@ -10018,7 +10089,13 @@ ${JSON.stringify(validation, null, 2)}`
10018
10089
  existingResource.behavior = behavior;
10019
10090
  }
10020
10091
  existingResource.updateAttributes(attributes);
10021
- await this.uploadMetadataFile();
10092
+ const newHash = this.generateDefinitionHash(existingResource.export(), existingResource.behavior);
10093
+ const existingMetadata2 = this.savedMetadata?.resources?.[name];
10094
+ const currentVersion = existingMetadata2?.currentVersion || "v0";
10095
+ const existingVersionData = existingMetadata2?.versions?.[currentVersion];
10096
+ if (!existingVersionData || existingVersionData.hash !== newHash) {
10097
+ await this.uploadMetadataFile();
10098
+ }
10022
10099
  this.emit("s3db.resourceUpdated", name);
10023
10100
  return existingResource;
10024
10101
  }