1.1.4 • Published 3 years ago

@pryv/stable-object-representation v1.1.4

Weekly downloads
-
License
BSD-3-Clause
Repository
github
Last release
3 years ago

Pryv Javascript tools to create checksums on Pryv.io data item

It provides utility to 1. Create a stable representation of a JSON object (all keys are ordered) 2. Makes a Hash string of this stable representation (default SHA256) 3. Creates a unique key to finds back the data item

Usage & Format

stringify: stableRepresentation.event.stringify(event)

Returns a "stable" JSON reprersentation of an event as described bellow.

hash: stableRepresentation.event.hash(event, [algorithm])

Returns a hash of "stable" JSON reprersentation of an event, prefixed with 'EVENT:O' and encoded in base64 following subresource integrity (SRI) specifcation See W3.org/TR/SRI. By default SHA256 is used.

Example: EVENT:0:sha256-X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=

key: stableRepresentation.event.key(event)

Returns a unique key for this event version.

compute: stableRepresentation.event.compute(event, [algorithm])

Returns an object equivalent of { key: key(event), hash: hash(event, algorithm) }

{
  key: 'EVENT:0:ckoxy0giw000hrs9yvi3rnlfm:1621578570.151',
  integrity: 'EVENT:0:sha256-X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE='
}

General rules to create stable representation of Pryv data

In this example we will use javascript as pseudo code examples.

  • Representation is a valid JSON object. JSON.parse(stableRep) must be valid. (stableRep; is a stable representation of a JSON object as a string.)
  • JSON representation should not have any 'spaces' between seprators. {"keyA":"valueA","keyB":["item0B","item1B"]} is valid,
    while {"keyA": "valueA", "keyB": ["item0B", "item1B"]} is not.
  • Numbers fields are represented without ".
    {"keyForNumericalValue":12.23} is valid,
    while {"keyForNumericalValue":"12.23"} is not.
  • Boolean fields are represented without ".
    {"keyForBooleanValue":false} is valid,
    while {"keyForBooleanValue":"false"} is not.
  • Array are kept is their original order. If order is modified stable representation differs.
  • Object fields are ordered by their UTF16 characters codes value. The folowing code exposes the logic implemented in javascript to be consumed by a sort() function.
/**
 * Compare two strings based on the UTF16 code value of their characters.
 * Characters are consumed one by one on each string. 
 * if the shortest string equals the first characters of the longest one, the shortest is before.
 * @param a
 * @param b
 * @returns {number} -1 if a is before b, 1 if b is before a, 0 if they are equals.
 */
function utf16StrCompare(a, b) {
  var lA = a.length;
  var lB = b.length;
  // default A is shorter and equals firstsB chars: A first
  var l = lA;
  var dres = -1;
  // B is shorter and equals firstsA chars: B first
  if (lA > lB) { l = lB; dres = -1; }
  // A and B are the same size
  if (lA === lB) {dres = 0; }

  var res;
  for (var i = 0; i < l; i++) {
    res = a.charCodeAt(i) - b.charCodeAt(i);
    if (res !== 0) {
      return res;
    }
  }
  return dres;
}

Event scheme hash: v0

. key . structure: {item code}:{item code version}:{item id}:{item version} usually the item version is the modified date property . They key is unique it is used to find a corresponding checksum. . integrity . structure: {item code}:{item code version}:{algorithm}-{checksum base64 encode}

Item code versionning (key)

. EVENT:0: correspond to item id = event.id and item version = event.modified . If event.modified is not present, then event.deleted is used. . ACCESS:0: correspond to item id =access.id and item version = access.modified . If access.modified is not present, then access.deleted is used.

Ckecksum versionning (hash)

. EVENT:0: correspond to encoding of current implementation of stableRepresentation.event.stringify0(event) . ACCESS:0: correspond to encoding of current implementation of stableRepresentation.access.stringify0(access)

Properties expected in an access object

Properties with a null values, will be ignored from the representation.

Special attention is required for

  • integrity: Obviously integrity is not taken for computation...
  • apiEndpoint: is ignored from computation (full domain name is part of settings not data)
  • lastUsed: is ignored as too dynamic...
  • calls: is ignored as too dynamic...

Properties expected in an event object

Properties with a null values, will be ignored from the representation.

Special attention is required for

  • integrity: Obviously integrity is not taken for computation...
  • tags: !! Are always ignored as deprecated and now included in streamIds
  • trashed: if false is ignored from the representation.
  • deleted: if null is ignored from the representation.
  • duration: if 0 is ignored from the representation <=> to undefined.
  • streamId: if exists is replaced by streamIds whith the value [streamId]
  • attachments.readToken: is ignored in the representation.

Example

{
  "id": "ciusga35r000sgwg4o1sr1j5q",
  "time": 1477575221.247,
  "streamId": "diary",
  "duration": 0,
  "type": "picture/attached",
  "tags": [],
  "description":  "test\"te\"st",
  "attachments": [
    {
      "id": "ciusga35r000tgwg4hcz2i22u",
      "fileName": "photo.jpg",
      "type": "image/jpeg",
      "size": 2561,
      "readToken": "cjasdashdhgad-asdjhasdhsdh"
    },
    {
      "id": "ciusga35r000tgwg4hcz2i32u",
      "fileName": "photo.jpg",
      "type": "image/jpeg",
      "size": 2561,
      "readToken": "cjasdashdhgad-asdjhasdhsdh"
    }
  ],
  "created": 1477575221.247,
  "createdBy": "ciusga33w0004gwg436uhtqs2",
  "modified": 1477575221.247,
  "modifiedBy": "ciusga33w0004gwg436uhtqs2",
  "trashed": false,
  "clientData": {
    "key2": "value2",
    "key1": "value1"
  }
}

Stable representation:

{"attachments":[{"fileName":"photo.jpg","id":"ciusga35r000tgwg4hcz2i22u","size":2561,"type":"image/jpeg"},{"fileName":"photo.jpg","id":"ciusga35r000tgwg4hcz2i32u","size":2561,"type":"image/jpeg"}],"clientData":{"key1":"value1","key2":"value2"},"created":1477575221.247,"createdBy":"ciusga33w0004gwg436uhtqs2","description":"test\"te\"st","id":"ciusga35r000sgwg4o1sr1j5q","modified":1477575221.247,"modifiedBy":"ciusga33w0004gwg436uhtqs2","streamId":"diary","time":1477575221.247,"type":"picture/attached"}

License

Copyright (C) 2020-2021 Pryv S.A. https://pryv.com This file is part of Open-Pryv.io and released under BSD-Clause-3 License SPDX-License-Identifier: BSD-3-Clause

1.1.4

3 years ago

1.1.1

3 years ago

1.1.3

3 years ago

1.1.2

3 years ago

1.1.0

3 years ago

1.0.9

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago