+
+ type |
+
-
+
+
+
+string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Source:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Returns:
-
-
-
- attribute belonging to this specific note (excludes inherited attributes)
-
-This method can be significantly faster than the getAttribute()
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<Attribute>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (async) getOwnedAttributes(typeopt, nameopt) → {Promise.<Array.<Attribute>>}
-
-
-
-
-
-
-
- This method is a faster variant of getAttributes() which looks for only owned attributes.
-Use when inheritance is not needed and/or in batch/performance sensitive operations.
-
-
-
-
-
-
-
-
-
-
- Parameters:
-
-
-
-
-
-
- | Name |
-
-
- Type |
-
-
- Attributes |
-
-
-
-
- Description |
-
-
-
-
-
-
-
-
- type |
-
-
-
-
-
-string
-
-
-
- |
+
+
@@ -3555,7 +3476,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -3595,7 +3516,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<Array.<Attribute>>
+Array.<Attribute>
@@ -3613,7 +3534,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getOwnedAttributeValue(type, name) → {Promise.<(string|null)>}
+ getOwnedAttributeValue(type, name) → {string|null}
@@ -3733,7 +3654,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -3773,7 +3694,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<(string|null)>
+string
+|
+
+null
@@ -3791,7 +3715,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getOwnedLabel(name) → {Promise.<(Attribute|null)>}
+ getOwnedLabel(name) → {Attribute|null}
@@ -3888,7 +3812,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -3928,7 +3852,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<(Attribute|null)>
+Attribute
+|
+
+null
@@ -3946,7 +3873,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getOwnedLabels(nameopt) → {Promise.<Array.<Attribute>>}
+ getOwnedLabels(nameopt) → {Array.<Attribute>}
@@ -4055,7 +3982,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -4095,7 +4022,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<Array.<Attribute>>
+Array.<Attribute>
@@ -4113,7 +4040,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getOwnedLabelValue(name) → {Promise.<(string|null)>}
+ getOwnedLabelValue(name) → {string|null}
@@ -4210,7 +4137,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -4250,7 +4177,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<(string|null)>
+string
+|
+
+null
@@ -4268,7 +4198,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getOwnedRelation(name) → {Promise.<(Attribute|null)>}
+ getOwnedRelation(name) → {Attribute|null}
@@ -4365,7 +4295,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -4405,7 +4335,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<(Attribute|null)>
+Attribute
+|
+
+null
@@ -4423,7 +4356,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getOwnedRelations(nameopt) → {Promise.<Array.<Attribute>>}
+ getOwnedRelations(nameopt) → {Array.<Attribute>}
@@ -4532,7 +4465,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -4572,7 +4505,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<Array.<Attribute>>
+Array.<Attribute>
@@ -4590,7 +4523,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getOwnedRelationTarget(name) → {Promise.<Note>|null}
+ getOwnedRelationTarget(name) → {Note|null}
@@ -4687,7 +4620,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -4727,7 +4660,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<Note>
+Note
|
null
@@ -4748,7 +4681,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getOwnedRelationValue(name) → {Promise.<(string|null)>}
+ getOwnedRelationValue(name) → {string|null}
@@ -4845,7 +4778,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -4885,7 +4818,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<(string|null)>
+string
+|
+
+null
@@ -4903,7 +4839,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getParentNotes() → {Promise.<Array.<Note>>}
+ getParentNotes() → {Array.<Note>}
@@ -4951,7 +4887,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -4991,7 +4927,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<Array.<Note>>
+Array.<Note>
@@ -5009,7 +4945,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getRelation(name) → {Promise.<(Attribute|null)>}
+ getRelation(name) → {Attribute|null}
@@ -5106,7 +5042,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -5146,7 +5082,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<(Attribute|null)>
+Attribute
+|
+
+null
@@ -5164,7 +5103,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getRelationDefinitions(nameopt) → {Promise.<Array.<Attribute>>}
+ getRelations(nameopt) → {Array.<Attribute>}
@@ -5273,7 +5212,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -5302,7 +5241,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- all note's relation definitions including inherited ones
+ all note's relations (attributes with type relation), including inherited ones
@@ -5313,7 +5252,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<Array.<Attribute>>
+Array.<Attribute>
@@ -5331,7 +5270,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getRelations(nameopt) → {Promise.<Array.<Attribute>>}
+ getRelationTarget(name) → {Note|null}
@@ -5359,8 +5298,6 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
| Type |
- Attributes |
-
@@ -5386,20 +5323,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-
- <optional>
-
-
-
-
-
- |
-
- relation name to filter |
+ |
@@ -5440,7 +5367,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -5469,7 +5396,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- all note's relations (attributes with type relation), including inherited ones
+ target note of the relation or null (if target is empty or note was not found)
@@ -5480,7 +5407,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-Promise.<Array.<Attribute>>
+Note
+|
+
+null
@@ -5498,7 +5428,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getRelationTarget(name) → {Promise.<Note>|null}
+ getRelationTargets(nameopt) → {Array.<Note>}
@@ -5526,6 +5456,8 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Type |
+ Attributes |
+
@@ -5551,10 +5483,20 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
+
+
+ <optional>
+
+
+
+
+
+ |
+
- |
+ relation name to filter |
@@ -5595,7 +5537,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Source:
@@ -5623,10 +5565,6 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Returns:
-
- target note of the relation or null (if target is empty or note was not found)
-
-
@@ -5635,10 +5573,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<Note>
-|
-
-null
+Array.<Note>
@@ -5656,7 +5591,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getRelationTargets(nameopt) → {Promise.<Array.<Note>>}
+ getRelationValue(name) → {string|null}
@@ -5684,8 +5619,6 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Type |
- Attributes |
-
@@ -5711,20 +5644,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-
- <optional>
-
-
-
-
-
- |
-
- relation name to filter |
+ relation name |
@@ -5765,7 +5688,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -5793,6 +5716,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
Returns:
+
+ relation value if relation exists, null otherwise
+
+
@@ -5801,7 +5728,10 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<Array.<Note>>
+string
+|
+
+null
@@ -5819,13 +5749,16 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getRelationValue(name) → {Promise.<(string|null)>}
+ getRevisions() → {Array.<NoteRevision>}
+
+ Returns note revisions of this note.
+
@@ -5834,190 +5767,32 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Parameters:
-
-
-
-
-
- | Name |
-
- Type |
-
-
- Description |
-
-
+
-
-
-
- name |
-
+
-
-
-
-string
+
+
-
- |
+
-
+
-
+
- relation name |
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Source:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Returns:
-
-
-
- relation value if relation exists, null otherwise
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<(string|null)>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (async) getRevisions() → {Promise.<Array.<NoteRevision>>}
-
-
-
-
-
-
-
- Returns note revisions of this note.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -6026,7 +5801,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -6062,7 +5837,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<Array.<NoteRevision>>
+Array.<NoteRevision>
@@ -6128,7 +5903,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -6186,7 +5961,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) getTargetRelations() → {Promise.<Array.<Attribute>>}
+ getTargetRelations() → {Array.<Attribute>}
@@ -6234,7 +6009,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -6274,7 +6049,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<Array.<Attribute>>
+Array.<Attribute>
@@ -6292,7 +6067,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) hasAttribute(type, name) → {Promise.<boolean>}
+ hasAttribute(type, name) → {boolean}
@@ -6412,7 +6187,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -6452,7 +6227,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<boolean>
+boolean
@@ -6470,7 +6245,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) hasChildren() → {boolean}
+ hasChildren() → {boolean}
@@ -6518,7 +6293,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -6576,7 +6351,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) hasLabel(name) → {Promise.<boolean>}
+ hasLabel(name) → {boolean}
@@ -6673,7 +6448,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -6713,7 +6488,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<boolean>
+boolean
@@ -6731,7 +6506,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) hasOwnedAttribute(type, name) → {Promise.<boolean>}
+ hasOwnedAttribute(type, name) → {boolean}
@@ -6851,7 +6626,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -6891,7 +6666,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<boolean>
+boolean
@@ -6909,7 +6684,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) hasOwnedLabel(name) → {Promise.<boolean>}
+ hasOwnedLabel(name) → {boolean}
@@ -7006,7 +6781,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -7046,7 +6821,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<boolean>
+boolean
@@ -7064,7 +6839,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) hasOwnedRelation(name) → {Promise.<boolean>}
+ hasOwnedRelation(name) → {boolean}
@@ -7161,7 +6936,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -7201,7 +6976,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<boolean>
+boolean
@@ -7219,7 +6994,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- (async) hasRelation(name) → {Promise.<boolean>}
+ hasRelation(name) → {boolean}
@@ -7316,7 +7091,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
- Source:
@@ -7356,7 +7131,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
-
-Promise.<boolean>
+boolean
@@ -7427,7 +7202,7 @@ Cache is note instance scoped.
- Source:
@@ -7463,7 +7238,7 @@ Cache is note instance scoped.
- (async) isDescendantOfNote(ancestorNoteId) → {Promise.<boolean>}
+ isDescendantOfNote(ancestorNoteId) → {boolean}
@@ -7555,7 +7330,7 @@ Cache is note instance scoped.
- Source:
@@ -7595,7 +7370,7 @@ Cache is note instance scoped.
-
-Promise.<boolean>
+boolean
@@ -7661,7 +7436,7 @@ Cache is note instance scoped.
- Source:
@@ -7767,7 +7542,7 @@ Cache is note instance scoped.
- Source:
@@ -7873,7 +7648,7 @@ Cache is note instance scoped.
- Source:
@@ -7979,7 +7754,7 @@ Cache is note instance scoped.
- Source:
@@ -8085,7 +7860,7 @@ Cache is note instance scoped.
- Source:
@@ -8143,109 +7918,7 @@ Cache is note instance scoped.
- (async) loadAttributesToCache() → {Promise.<void>}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Source:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (async) removeAttribute(type, name, valueopt) → {Promise.<void>}
+ removeAttribute(type, name, valueopt)
@@ -8420,7 +8093,7 @@ Cache is note instance scoped.
- Source:
@@ -8445,39 +8118,21 @@ Cache is note instance scoped.
-Returns:
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
+
+
+
+ removeLabel(name, valueopt)
+
-
-
-
-
-
-
-
-
-
- (async) removeLabel(name, valueopt) → {Promise.<void>}
-
-
-
+
@@ -8618,7 +8273,7 @@ Cache is note instance scoped.
- Source:
@@ -8643,24 +8298,6 @@ Cache is note instance scoped.
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
-
-
-
-
@@ -8672,7 +8309,7 @@ Cache is note instance scoped.
- (async) removeRelation(name, valueopt) → {Promise.<void>}
+ removeRelation(name, valueopt)
@@ -8816,7 +8453,7 @@ Cache is note instance scoped.
- Source:
@@ -8841,24 +8478,6 @@ Cache is note instance scoped.
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
-
-
-
-
@@ -8870,7 +8489,7 @@ Cache is note instance scoped.
- (async) setAttribute(type, name, valueopt) → {Promise.<void>}
+ setAttribute(type, name, valueopt)
@@ -9045,211 +8664,7 @@ Cache is note instance scoped.
- Source:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (async) setContent() → {Promise}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Source:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (async) setJsonContent() → {Promise}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Source:
-
@@ -9274,24 +8689,6 @@ Cache is note instance scoped.
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise
-
-
-
-
-
-
@@ -9303,7 +8700,7 @@ Cache is note instance scoped.
- (async) setLabel(name, valueopt) → {Promise.<void>}
+ setLabel(name, valueopt)
@@ -9447,7 +8844,7 @@ Cache is note instance scoped.
- Source:
@@ -9472,24 +8869,6 @@ Cache is note instance scoped.
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
-
-
-
-
@@ -9501,7 +8880,7 @@ Cache is note instance scoped.
- (async) setRelation(name, valueopt) → {Promise.<void>}
+ setRelation(name, valueopt)
@@ -9645,7 +9024,7 @@ Cache is note instance scoped.
- Source:
@@ -9670,24 +9049,6 @@ Cache is note instance scoped.
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
-
-
-
-
@@ -9699,7 +9060,7 @@ Cache is note instance scoped.
- (async) toggleAttribute(type, enabled, name, valueopt) → {Promise.<void>}
+ toggleAttribute(type, enabled, name, valueopt)
@@ -9905,7 +9266,7 @@ Cache is note instance scoped.
- Source:
@@ -9930,24 +9291,6 @@ Cache is note instance scoped.
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
-
-
-
-
@@ -9959,7 +9302,7 @@ Cache is note instance scoped.
- (async) toggleLabel(enabled, name, valueopt) → {Promise.<void>}
+ toggleLabel(enabled, name, valueopt)
@@ -10134,7 +9477,7 @@ Cache is note instance scoped.
- Source:
@@ -10159,24 +9502,6 @@ Cache is note instance scoped.
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
-
-
-
-
@@ -10188,7 +9513,7 @@ Cache is note instance scoped.
- (async) toggleRelation(enabled, name, valueopt) → {Promise.<void>}
+ toggleRelation(enabled, name, valueopt)
@@ -10363,7 +9688,7 @@ Cache is note instance scoped.
- Source:
@@ -10388,24 +9713,6 @@ Cache is note instance scoped.
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise.<void>
-
-
-
-
-
-
@@ -10433,7 +9740,7 @@ Cache is note instance scoped.
diff --git a/docs/backend_api/NoteRevision.html b/docs/backend_api/NoteRevision.html
index e75e06cde..2194ae2fa 100644
--- a/docs/backend_api/NoteRevision.html
+++ b/docs/backend_api/NoteRevision.html
@@ -198,29 +198,6 @@
- |
-
-
-
-
-
-
- contentLength |
-
-
-
-
-
-int
-
-
-
- |
-
-
-
-
-
|
@@ -421,7 +398,7 @@
- Source:
@@ -488,7 +465,7 @@
- (async) getContent() → {Promise.<*>}
+ getContent() → {*}
@@ -536,7 +513,7 @@
- Source:
@@ -572,7 +549,7 @@
-
-Promise.<*>
+*
@@ -638,7 +615,7 @@
- Source:
@@ -691,108 +668,6 @@
-
-
-
-
-
- (async) setContent() → {Promise}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Source:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Returns:
-
-
-
-
-
- -
- Type
-
- -
-
-Promise
-
-
-
-
-
-
-
-
-
-
-
-
@@ -814,7 +689,7 @@
diff --git a/docs/backend_api/Option.html b/docs/backend_api/Option.html
index c314ec75b..b65e9eb5e 100644
--- a/docs/backend_api/Option.html
+++ b/docs/backend_api/Option.html
@@ -237,7 +237,7 @@
- Source:
@@ -316,7 +316,7 @@
diff --git a/docs/backend_api/RecentNote.html b/docs/backend_api/RecentNote.html
index 5691dac95..b4d473056 100644
--- a/docs/backend_api/RecentNote.html
+++ b/docs/backend_api/RecentNote.html
@@ -293,7 +293,7 @@
diff --git a/docs/backend_api/entities_api_token.js.html b/docs/backend_api/entities_api_token.js.html
index 989b211a9..0d4db291c 100644
--- a/docs/backend_api/entities_api_token.js.html
+++ b/docs/backend_api/entities_api_token.js.html
@@ -75,7 +75,7 @@ module.exports = ApiToken;
diff --git a/docs/backend_api/entities_attribute.js.html b/docs/backend_api/entities_attribute.js.html
index 031da57b1..abf4502c9 100644
--- a/docs/backend_api/entities_attribute.js.html
+++ b/docs/backend_api/entities_attribute.js.html
@@ -28,21 +28,22 @@
"use strict";
+
const Entity = require('./entity');
-const repository = require('../services/repository');
const dateUtils = require('../services/date_utils');
const sql = require('../services/sql');
+const promotedAttributeDefinitionParser = require("../services/promoted_attribute_definition_parser");
/**
* Attribute is key value pair owned by a note.
*
- * @property {string} attributeId
- * @property {string} noteId
- * @property {string} type
- * @property {string} name
+ * @property {string} attributeId - immutable
+ * @property {string} noteId - immutable
+ * @property {string} type - immutable
+ * @property {string} name - immutable
* @property {string} value
* @property {int} position
- * @property {boolean} isInheritable
+ * @property {boolean} isInheritable - immutable
* @property {boolean} isDeleted
* @property {string|null} deleteId - ID identifying delete transaction
* @property {string} utcDateCreated
@@ -59,27 +60,19 @@ class Attribute extends Entity {
super(row);
this.isInheritable = !!this.isInheritable;
-
- if (this.isDefinition()) {
- try {
- this.value = JSON.parse(this.value);
- }
- catch (e) {
- }
- }
}
/**
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
- async getNote() {
- return await repository.getNote(this.noteId);
+ getNote() {
+ return this.repository.getNote(this.noteId);
}
/**
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
- async getTargetNote() {
+ getTargetNote() {
if (this.type !== 'relation') {
throw new Error(`Attribute ${this.attributeId} is not relation`);
}
@@ -88,17 +81,31 @@ class Attribute extends Entity {
return null;
}
- return await repository.getNote(this.value);
+ return this.repository.getNote(this.value);
}
/**
* @return {boolean}
*/
isDefinition() {
- return this.type === 'label-definition' || this.type === 'relation-definition';
+ return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
+ }
+
+ getDefinition() {
+ return promotedAttributeDefinitionParser.parse(this.value);
+ }
+
+ getDefinedName() {
+ if (this.type === 'label' && this.name.startsWith('label:')) {
+ return this.name.substr(6);
+ } else if (this.type === 'label' && this.name.startsWith('relation:')) {
+ return this.name.substr(9);
+ } else {
+ return this.name;
+ }
}
- async beforeSaving() {
+ beforeSaving() {
if (!this.value) {
if (this.type === 'relation') {
throw new Error(`Cannot save relation ${this.name} since it does not target any note.`);
@@ -109,7 +116,7 @@ class Attribute extends Entity {
}
if (this.position === undefined) {
- this.position = 1 + await sql.getValue(`SELECT COALESCE(MAX(position), 0) FROM attributes WHERE noteId = ?`, [this.noteId]);
+ this.position = 1 + sql.getValue(`SELECT COALESCE(MAX(position), 0) FROM attributes WHERE noteId = ?`, [this.noteId]);
}
if (!this.isInheritable) {
@@ -131,20 +138,14 @@ class Attribute extends Entity {
}
}
- // cannot be static!
- updatePojo(pojo) {
- delete pojo.isOwned;
- delete pojo.__note;
- }
-
- createClone(type, name, value) {
+ createClone(type, name, value, isInheritable) {
return new Attribute({
noteId: this.noteId,
type: type,
name: name,
value: value,
position: this.position,
- isInheritable: this.isInheritable,
+ isInheritable: isInheritable,
isDeleted: false,
utcDateCreated: this.utcDateCreated,
utcDateModified: this.utcDateModified
@@ -152,7 +153,8 @@ class Attribute extends Entity {
}
}
-module.exports = Attribute;
+module.exports = Attribute;
+
@@ -168,7 +170,7 @@ module.exports = Attribute;
diff --git a/docs/backend_api/entities_branch.js.html b/docs/backend_api/entities_branch.js.html
index 0974e918b..2dca97bcb 100644
--- a/docs/backend_api/entities_branch.js.html
+++ b/docs/backend_api/entities_branch.js.html
@@ -30,16 +30,15 @@
const Entity = require('./entity');
const dateUtils = require('../services/date_utils');
-const repository = require('../services/repository');
const sql = require('../services/sql');
/**
* Branch represents note's placement in the tree - it's essentially pair of noteId and parentNoteId.
* Each note can have multiple (at least one) branches, meaning it can be placed into multiple places in the tree.
*
- * @property {string} branchId - primary key
- * @property {string} noteId
- * @property {string} parentNoteId
+ * @property {string} branchId - primary key, immutable
+ * @property {string} noteId - immutable
+ * @property {string} parentNoteId - immutable
* @property {int} notePosition
* @property {string} prefix
* @property {boolean} isExpanded
@@ -56,19 +55,19 @@ class Branch extends Entity {
// notePosition is not part of hash because it would produce a lot of updates in case of reordering
static get hashedProperties() { return ["branchId", "noteId", "parentNoteId", "isDeleted", "deleteId", "prefix"]; }
- /** @returns {Promise<Note|null>} */
- async getNote() {
- return await repository.getNote(this.noteId);
+ /** @returns {Note|null} */
+ getNote() {
+ return this.repository.getNote(this.noteId);
}
- /** @returns {Promise<Note|null>} */
- async getParentNote() {
- return await repository.getNote(this.parentNoteId);
+ /** @returns {Note|null} */
+ getParentNote() {
+ return this.repository.getNote(this.parentNoteId);
}
- async beforeSaving() {
+ beforeSaving() {
if (this.notePosition === undefined) {
- const maxNotePos = await sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [this.parentNoteId]);
+ const maxNotePos = sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [this.parentNoteId]);
this.notePosition = maxNotePos === null ? 0 : maxNotePos + 10;
}
@@ -105,7 +104,8 @@ class Branch extends Entity {
}
}
-module.exports = Branch;
+module.exports = Branch;
+
@@ -121,7 +121,7 @@ module.exports = Branch;
diff --git a/docs/backend_api/entities_entity.js.html b/docs/backend_api/entities_entity.js.html
index a51e29a00..d398acf49 100644
--- a/docs/backend_api/entities_entity.js.html
+++ b/docs/backend_api/entities_entity.js.html
@@ -29,6 +29,7 @@
"use strict";
const utils = require('../services/utils');
+let repo = null;
class Entity {
/**
@@ -53,14 +54,7 @@ class Entity {
const origHash = this.hash;
this.hash = this.generateHash();
-
- if (this.forcedChange) {
- this.isChanged = true;
- delete this.forcedChange;
- }
- else {
- this.isChanged = origHash !== this.hash;
- }
+ this.isChanged = origHash !== this.hash;
}
generateIdIfNecessary() {
@@ -79,14 +73,23 @@ class Entity {
return utils.hash(contentToHash).substr(0, 10);
}
- async save() {
- await require('../services/repository').updateEntity(this);
+ get repository() {
+ if (!repo) {
+ repo = require('../services/repository');
+ }
+
+ return repo;
+ }
+
+ save() {
+ this.repository.updateEntity(this);
return this;
}
}
-module.exports = Entity;
+module.exports = Entity;
+
@@ -102,7 +105,7 @@ module.exports = Entity;
diff --git a/docs/backend_api/entities_note.js.html b/docs/backend_api/entities_note.js.html
index eb01e6e38..bfd2d1246 100644
--- a/docs/backend_api/entities_note.js.html
+++ b/docs/backend_api/entities_note.js.html
@@ -31,16 +31,13 @@
const Entity = require('./entity');
const Attribute = require('./attribute');
const protectedSessionService = require('../services/protected_session');
-const repository = require('../services/repository');
const sql = require('../services/sql');
const utils = require('../services/utils');
const dateUtils = require('../services/date_utils');
-const syncTableService = require('../services/sync_table');
+const entityChangesService = require('../services/entity_changes.js');
const LABEL = 'label';
-const LABEL_DEFINITION = 'label-definition';
const RELATION = 'relation';
-const RELATION_DEFINITION = 'relation-definition';
/**
* This represents a Note which is a central object in the Trilium Notes project.
@@ -49,7 +46,6 @@ const RELATION_DEFINITION = 'relation-definition';
* @property {string} type - one of "text", "code", "file" or "render"
* @property {string} mime - MIME type, e.g. "text/html"
* @property {string} title - note title
- * @property {int} contentLength - length of content
* @property {boolean} isProtected - true if note is protected
* @property {boolean} isDeleted - true if note is deleted
* @property {string|null} deleteId - ID identifying delete transaction
@@ -95,14 +91,14 @@ class Note extends Entity {
* part of Note entity with it's own sync. Reasons behind this hybrid design has been:
*
* - content can be quite large and it's not necessary to load it / fill memory for any note access even if we don't need a content, especially for bulk operations like search
- * - changes in the note metadata or title should not trigger note content sync (so we keep separate utcDateModified and sync rows)
+ * - changes in the note metadata or title should not trigger note content sync (so we keep separate utcDateModified and entity changes records)
* - but to the user note content and title changes are one and the same - single dateModified (so all changes must go through Note and content is not a separate entity)
*/
- /** @returns {Promise<*>} */
- async getContent(silentNotFoundError = false) {
+ /** @returns {*} */
+ getContent(silentNotFoundError = false) {
if (this.content === undefined) {
- const res = await sql.getRow(`SELECT content, hash FROM note_contents WHERE noteId = ?`, [this.noteId]);
+ const res = sql.getRow(`SELECT content, hash FROM note_contents WHERE noteId = ?`, [this.noteId]);
if (!res) {
if (silentNotFoundError) {
@@ -135,9 +131,20 @@ class Note extends Entity {
}
}
- /** @returns {Promise<*>} */
- async getJsonContent() {
- const content = await this.getContent();
+ /** @returns {{contentLength, dateModified, utcDateModified}} */
+ getContentMetadata() {
+ return sql.getRow(`
+ SELECT
+ LENGTH(content) AS contentLength,
+ dateModified,
+ utcDateModified
+ FROM note_contents
+ WHERE noteId = ?`, [this.noteId]);
+ }
+
+ /** @returns {*} */
+ getJsonContent() {
+ const content = this.getContent();
if (!content || !content.trim()) {
return null;
@@ -146,24 +153,24 @@ class Note extends Entity {
return JSON.parse(content);
}
- /** @returns {Promise} */
- async setContent(content) {
+ setContent(content) {
if (content === null || content === undefined) {
throw new Error(`Cannot set null content to note ${this.noteId}`);
}
- content = Buffer.isBuffer(content) ? content : Buffer.from(content);
-
- // force updating note itself so that dateModified is represented correctly even for the content
- this.forcedChange = true;
- this.contentLength = content.byteLength;
- await this.save();
+ if (this.isStringNote()) {
+ content = content.toString();
+ }
+ else {
+ content = Buffer.isBuffer(content) ? content : Buffer.from(content);
+ }
this.content = content;
const pojo = {
noteId: this.noteId,
content: content,
+ dateModified: dateUtils.localNowDateTime(),
utcDateModified: dateUtils.utcNowDateTime(),
hash: utils.hash(this.noteId + "|" + content.toString())
};
@@ -177,14 +184,13 @@ class Note extends Entity {
}
}
- await sql.upsert("note_contents", "noteId", pojo);
+ sql.upsert("note_contents", "noteId", pojo);
- await syncTableService.addNoteContentSync(this.noteId);
+ entityChangesService.addNoteContentEntityChange(this.noteId);
}
- /** @returns {Promise} */
- async setJsonContent(content) {
- await this.setContent(JSON.stringify(content, null, '\t'));
+ setJsonContent(content) {
+ this.setContent(JSON.stringify(content, null, '\t'));
}
/** @returns {boolean} true if this note is the root of the note tree. Root note has "root" noteId */
@@ -232,8 +238,8 @@ class Note extends Entity {
return null;
}
- async loadOwnedAttributesToCache() {
- this.__ownedAttributeCache = await repository.getEntities(`SELECT * FROM attributes WHERE isDeleted = 0 AND noteId = ?`, [this.noteId]);
+ loadOwnedAttributesToCache() {
+ this.__ownedAttributeCache = this.repository.getEntities(`SELECT * FROM attributes WHERE isDeleted = 0 AND noteId = ?`, [this.noteId]);
return this.__ownedAttributeCache;
}
@@ -243,11 +249,11 @@ class Note extends Entity {
*
* @param {string} [type] - (optional) attribute type to filter
* @param {string} [name] - (optional) attribute name to filter
- * @returns {Promise<Attribute[]>} note's "owned" attributes - excluding inherited ones
+ * @returns {Attribute[]} note's "owned" attributes - excluding inherited ones
*/
- async getOwnedAttributes(type, name) {
+ getOwnedAttributes(type, name) {
if (!this.__ownedAttributeCache) {
- await this.loadOwnedAttributesToCache();
+ this.loadOwnedAttributesToCache();
}
if (type && name) {
@@ -265,31 +271,31 @@ class Note extends Entity {
}
/**
- * @returns {Promise<Attribute>} attribute belonging to this specific note (excludes inherited attributes)
+ * @returns {Attribute} attribute belonging to this specific note (excludes inherited attributes)
*
* This method can be significantly faster than the getAttribute()
*/
- async getOwnedAttribute(type, name) {
- const attrs = await this.getOwnedAttributes(type, name);
+ getOwnedAttribute(type, name) {
+ const attrs = this.getOwnedAttributes(type, name);
return attrs.length > 0 ? attrs[0] : null;
}
/**
- * @returns {Promise<Attribute[]>} relations targetting this specific note
+ * @returns {Attribute[]} relations targetting this specific note
*/
- async getTargetRelations() {
- return await repository.getEntities("SELECT * FROM attributes WHERE type = 'relation' AND isDeleted = 0 AND value = ?", [this.noteId]);
+ getTargetRelations() {
+ return this.repository.getEntities("SELECT * FROM attributes WHERE type = 'relation' AND isDeleted = 0 AND value = ?", [this.noteId]);
}
/**
* @param {string} [type] - (optional) attribute type to filter
* @param {string} [name] - (optional) attribute name to filter
- * @returns {Promise<Attribute[]>} all note's attributes, including inherited ones
+ * @returns {Attribute[]} all note's attributes, including inherited ones
*/
- async getAttributes(type, name) {
+ getAttributes(type, name) {
if (!this.__attributeCache) {
- await this.loadAttributesToCache();
+ this.loadAttributesToCache();
}
if (type && name) {
@@ -308,67 +314,51 @@ class Note extends Entity {
/**
* @param {string} [name] - label name to filter
- * @returns {Promise<Attribute[]>} all note's labels (attributes with type label), including inherited ones
+ * @returns {Attribute[]} all note's labels (attributes with type label), including inherited ones
*/
- async getLabels(name) {
- return await this.getAttributes(LABEL, name);
+ getLabels(name) {
+ return this.getAttributes(LABEL, name);
}
/**
* @param {string} [name] - label name to filter
- * @returns {Promise<Attribute[]>} all note's labels (attributes with type label), excluding inherited ones
+ * @returns {Attribute[]} all note's labels (attributes with type label), excluding inherited ones
*/
- async getOwnedLabels(name) {
- return await this.getOwnedAttributes(LABEL, name);
- }
-
- /**
- * @param {string} [name] - label name to filter
- * @returns {Promise<Attribute[]>} all note's label definitions, including inherited ones
- */
- async getLabelDefinitions(name) {
- return await this.getAttributes(LABEL_DEFINITION, name);
+ getOwnedLabels(name) {
+ return this.getOwnedAttributes(LABEL, name);
}
/**
* @param {string} [name] - relation name to filter
- * @returns {Promise<Attribute[]>} all note's relations (attributes with type relation), including inherited ones
+ * @returns {Attribute[]} all note's relations (attributes with type relation), including inherited ones
*/
- async getRelations(name) {
- return await this.getAttributes(RELATION, name);
+ getRelations(name) {
+ return this.getAttributes(RELATION, name);
}
/**
* @param {string} [name] - relation name to filter
- * @returns {Promise<Attribute[]>} all note's relations (attributes with type relation), excluding inherited ones
+ * @returns {Attribute[]} all note's relations (attributes with type relation), excluding inherited ones
*/
- async getOwnedRelations(name) {
- return await this.getOwnedAttributes(RELATION, name);
+ getOwnedRelations(name) {
+ return this.getOwnedAttributes(RELATION, name);
}
/**
* @param {string} [name] - relation name to filter
- * @returns {Promise<Note[]>}
+ * @returns {Note[]}
*/
- async getRelationTargets(name) {
- const relations = await this.getRelations(name);
+ getRelationTargets(name) {
+ const relations = this.getRelations(name);
const targets = [];
for (const relation of relations) {
- targets.push(await relation.getTargetNote());
+ targets.push(relation.getTargetNote());
}
return targets;
}
- /**
- * @param {string} [name] - relation name to filter
- * @returns {Promise<Attribute[]>} all note's relation definitions including inherited ones
- */
- async getRelationDefinitions(name) {
- return await this.getAttributes(RELATION_DEFINITION, name);
- }
-
/**
* Clear note's attributes cache to force fresh reload for next attribute request.
* Cache is note instance scoped.
@@ -378,9 +368,8 @@ class Note extends Entity {
this.__ownedAttributeCache = null;
}
- /** @returns {Promise<void>} */
- async loadAttributesToCache() {
- const attributes = await repository.getEntities(`
+ loadAttributesToCache() {
+ const attributes = this.repository.getEntities(`
WITH RECURSIVE
tree(noteId, level) AS (
SELECT ?, 0
@@ -412,6 +401,7 @@ class Note extends Entity {
return false;
}
+ // FIXME: this code is quite questionable, one problem is that other caches (TreeCache, NoteCache) have nothing like that
if (attr.isDefinition()) {
const firstDefinitionIndex = attributes.findIndex(el => el.type === attr.type && el.name === attr.name);
@@ -419,15 +409,15 @@ class Note extends Entity {
return firstDefinitionIndex === index;
}
else {
- const definitionAttr = attributes.find(el => el.type === attr.type + '-definition' && el.name === attr.name);
+ const definitionAttr = attributes.find(el => el.type === 'label' && el.name === attr.type + ':' + attr.name);
if (!definitionAttr) {
return true;
}
- const definition = definitionAttr.value;
+ const definition = definitionAttr.getDefinition();
- if (definition.multiplicityType === 'multivalue') {
+ if (definition.multiplicity === 'multi') {
return true;
}
else {
@@ -439,38 +429,34 @@ class Note extends Entity {
}
});
- for (const attr of filteredAttributes) {
- attr.isOwned = attr.noteId === this.noteId;
- }
-
this.__attributeCache = filteredAttributes;
}
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
- * @returns {Promise<boolean>} true if note has an attribute with given type and name (including inherited)
+ * @returns {boolean} true if note has an attribute with given type and name (including inherited)
*/
- async hasAttribute(type, name) {
- return !!await this.getAttribute(type, name);
+ hasAttribute(type, name) {
+ return !!this.getAttribute(type, name);
}
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
- * @returns {Promise<boolean>} true if note has an attribute with given type and name (excluding inherited)
+ * @returns {boolean} true if note has an attribute with given type and name (excluding inherited)
*/
- async hasOwnedAttribute(type, name) {
- return !!await this.getOwnedAttribute(type, name);
+ hasOwnedAttribute(type, name) {
+ return !!this.getOwnedAttribute(type, name);
}
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
- * @returns {Promise<Attribute>} attribute of given type and name. If there's more such attributes, first is returned. Returns null if there's no such attribute belonging to this note.
+ * @returns {Attribute} attribute of given type and name. If there's more such attributes, first is returned. Returns null if there's no such attribute belonging to this note.
*/
- async getAttribute(type, name) {
- const attributes = await this.getAttributes();
+ getAttribute(type, name) {
+ const attributes = this.getAttributes();
return attributes.find(attr => attr.type === type && attr.name === name);
}
@@ -478,10 +464,10 @@ class Note extends Entity {
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
- * @returns {Promise<string|null>} attribute value of given type and name or null if no such attribute exists.
+ * @returns {string|null} attribute value of given type and name or null if no such attribute exists.
*/
- async getAttributeValue(type, name) {
- const attr = await this.getAttribute(type, name);
+ getAttributeValue(type, name) {
+ const attr = this.getAttribute(type, name);
return attr ? attr.value : null;
}
@@ -489,10 +475,10 @@ class Note extends Entity {
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
- * @returns {Promise<string|null>} attribute value of given type and name or null if no such attribute exists.
+ * @returns {string|null} attribute value of given type and name or null if no such attribute exists.
*/
- async getOwnedAttributeValue(type, name) {
- const attr = await this.getOwnedAttribute(type, name);
+ getOwnedAttributeValue(type, name) {
+ const attr = this.getOwnedAttribute(type, name);
return attr ? attr.value : null;
}
@@ -504,14 +490,13 @@ class Note extends Entity {
* @param {boolean} enabled - toggle On or Off
* @param {string} name - attribute name
* @param {string} [value] - attribute value (optional)
- * @returns {Promise<void>}
*/
- async toggleAttribute(type, enabled, name, value) {
+ toggleAttribute(type, enabled, name, value) {
if (enabled) {
- await this.setAttribute(type, name, value);
+ this.setAttribute(type, name, value);
}
else {
- await this.removeAttribute(type, name, value);
+ this.removeAttribute(type, name, value);
}
}
@@ -521,16 +506,15 @@ class Note extends Entity {
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @param {string} [value] - attribute value (optional)
- * @returns {Promise<void>}
*/
- async setAttribute(type, name, value) {
- const attributes = await this.loadOwnedAttributesToCache();
+ setAttribute(type, name, value) {
+ const attributes = this.loadOwnedAttributesToCache();
let attr = attributes.find(attr => attr.type === type && attr.name === name);
if (attr) {
if (attr.value !== value) {
attr.value = value;
- await attr.save();
+ attr.save();
this.invalidateAttributeCache();
}
@@ -543,7 +527,7 @@ class Note extends Entity {
value: value !== undefined ? value : ""
});
- await attr.save();
+ attr.save();
this.invalidateAttributeCache();
}
@@ -555,15 +539,14 @@ class Note extends Entity {
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @param {string} [value] - attribute value (optional)
- * @returns {Promise<void>}
*/
- async removeAttribute(type, name, value) {
- const attributes = await this.loadOwnedAttributesToCache();
+ removeAttribute(type, name, value) {
+ const attributes = this.loadOwnedAttributesToCache();
for (const attribute of attributes) {
if (attribute.type === type && attribute.name === name && (value === undefined || value === attribute.value)) {
attribute.isDeleted = true;
- await attribute.save();
+ attribute.save();
this.invalidateAttributeCache();
}
@@ -571,121 +554,123 @@ class Note extends Entity {
}
/**
- * @return {Promise<Attribute>}
+ * @return {Attribute}
*/
- async addAttribute(type, name, value = "") {
+ addAttribute(type, name, value = "", isInheritable = false, position = 1000) {
const attr = new Attribute({
noteId: this.noteId,
type: type,
name: name,
- value: value
+ value: value,
+ isInheritable: isInheritable,
+ position: position
});
- await attr.save();
+ attr.save();
this.invalidateAttributeCache();
return attr;
}
- async addLabel(name, value = "") {
- return await this.addAttribute(LABEL, name, value);
+ addLabel(name, value = "", isInheritable = false) {
+ return this.addAttribute(LABEL, name, value, isInheritable);
}
- async addRelation(name, targetNoteId) {
- return await this.addAttribute(RELATION, name, targetNoteId);
+ addRelation(name, targetNoteId, isInheritable = false) {
+ return this.addAttribute(RELATION, name, targetNoteId, isInheritable);
}
/**
* @param {string} name - label name
- * @returns {Promise<boolean>} true if label exists (including inherited)
+ * @returns {boolean} true if label exists (including inherited)
*/
- async hasLabel(name) { return await this.hasAttribute(LABEL, name); }
+ hasLabel(name) { return this.hasAttribute(LABEL, name); }
/**
* @param {string} name - label name
- * @returns {Promise<boolean>} true if label exists (excluding inherited)
+ * @returns {boolean} true if label exists (excluding inherited)
*/
- async hasOwnedLabel(name) { return await this.hasOwnedAttribute(LABEL, name); }
+ hasOwnedLabel(name) { return this.hasOwnedAttribute(LABEL, name); }
/**
* @param {string} name - relation name
- * @returns {Promise<boolean>} true if relation exists (including inherited)
+ * @returns {boolean} true if relation exists (including inherited)
*/
- async hasRelation(name) { return await this.hasAttribute(RELATION, name); }
+ hasRelation(name) { return this.hasAttribute(RELATION, name); }
/**
* @param {string} name - relation name
- * @returns {Promise<boolean>} true if relation exists (excluding inherited)
+ * @returns {boolean} true if relation exists (excluding inherited)
*/
- async hasOwnedRelation(name) { return await this.hasOwnedAttribute(RELATION, name); }
+ hasOwnedRelation(name) { return this.hasOwnedAttribute(RELATION, name); }
/**
* @param {string} name - label name
- * @returns {Promise<Attribute|null>} label if it exists, null otherwise
+ * @returns {Attribute|null} label if it exists, null otherwise
*/
- async getLabel(name) { return await this.getAttribute(LABEL, name); }
+ getLabel(name) { return this.getAttribute(LABEL, name); }
/**
* @param {string} name - label name
- * @returns {Promise<Attribute|null>} label if it exists, null otherwise
+ * @returns {Attribute|null} label if it exists, null otherwise
*/
- async getOwnedLabel(name) { return await this.getOwnedAttribute(LABEL, name); }
+ getOwnedLabel(name) { return this.getOwnedAttribute(LABEL, name); }
/**
* @param {string} name - relation name
- * @returns {Promise<Attribute|null>} relation if it exists, null otherwise
+ * @returns {Attribute|null} relation if it exists, null otherwise
*/
- async getRelation(name) { return await this.getAttribute(RELATION, name); }
+ getRelation(name) { return this.getAttribute(RELATION, name); }
/**
* @param {string} name - relation name
- * @returns {Promise<Attribute|null>} relation if it exists, null otherwise
+ * @returns {Attribute|null} relation if it exists, null otherwise
*/
- async getOwnedRelation(name) { return await this.getOwnedAttribute(RELATION, name); }
+ getOwnedRelation(name) { return this.getOwnedAttribute(RELATION, name); }
/**
* @param {string} name - label name
- * @returns {Promise<string|null>} label value if label exists, null otherwise
+ * @returns {string|null} label value if label exists, null otherwise
*/
- async getLabelValue(name) { return await this.getAttributeValue(LABEL, name); }
+ getLabelValue(name) { return this.getAttributeValue(LABEL, name); }
/**
* @param {string} name - label name
- * @returns {Promise<string|null>} label value if label exists, null otherwise
+ * @returns {string|null} label value if label exists, null otherwise
*/
- async getOwnedLabelValue(name) { return await this.getOwnedAttributeValue(LABEL, name); }
+ getOwnedLabelValue(name) { return this.getOwnedAttributeValue(LABEL, name); }
/**
* @param {string} name - relation name
- * @returns {Promise<string|null>} relation value if relation exists, null otherwise
+ * @returns {string|null} relation value if relation exists, null otherwise
*/
- async getRelationValue(name) { return await this.getAttributeValue(RELATION, name); }
+ getRelationValue(name) { return this.getAttributeValue(RELATION, name); }
/**
* @param {string} name - relation name
- * @returns {Promise<string|null>} relation value if relation exists, null otherwise
+ * @returns {string|null} relation value if relation exists, null otherwise
*/
- async getOwnedRelationValue(name) { return await this.getOwnedAttributeValue(RELATION, name); }
+ getOwnedRelationValue(name) { return this.getOwnedAttributeValue(RELATION, name); }
/**
* @param {string} name
- * @returns {Promise<Note>|null} target note of the relation or null (if target is empty or note was not found)
+ * @returns {Note|null} target note of the relation or null (if target is empty or note was not found)
*/
- async getRelationTarget(name) {
- const relation = await this.getRelation(name);
+ getRelationTarget(name) {
+ const relation = this.getRelation(name);
- return relation ? await repository.getNote(relation.value) : null;
+ return relation ? this.repository.getNote(relation.value) : null;
}
/**
* @param {string} name
- * @returns {Promise<Note>|null} target note of the relation or null (if target is empty or note was not found)
+ * @returns {Note|null} target note of the relation or null (if target is empty or note was not found)
*/
- async getOwnedRelationTarget(name) {
- const relation = await this.getOwnedRelation(name);
+ getOwnedRelationTarget(name) {
+ const relation = this.getOwnedRelation(name);
- return relation ? await repository.getNote(relation.value) : null;
+ return relation ? this.repository.getNote(relation.value) : null;
}
/**
@@ -694,9 +679,8 @@ class Note extends Entity {
* @param {boolean} enabled - toggle On or Off
* @param {string} name - label name
* @param {string} [value] - label value (optional)
- * @returns {Promise<void>}
*/
- async toggleLabel(enabled, name, value) { return await this.toggleAttribute(LABEL, enabled, name, value); }
+ toggleLabel(enabled, name, value) { return this.toggleAttribute(LABEL, enabled, name, value); }
/**
* Based on enabled, relation is either set or removed.
@@ -704,51 +688,46 @@ class Note extends Entity {
* @param {boolean} enabled - toggle On or Off
* @param {string} name - relation name
* @param {string} [value] - relation value (noteId)
- * @returns {Promise<void>}
*/
- async toggleRelation(enabled, name, value) { return await this.toggleAttribute(RELATION, enabled, name, value); }
+ toggleRelation(enabled, name, value) { return this.toggleAttribute(RELATION, enabled, name, value); }
/**
* Update's given label's value or creates it if it doesn't exist
*
* @param {string} name - label name
* @param {string} [value] - label value
- * @returns {Promise<void>}
*/
- async setLabel(name, value) { return await this.setAttribute(LABEL, name, value); }
+ setLabel(name, value) { return this.setAttribute(LABEL, name, value); }
/**
* Update's given relation's value or creates it if it doesn't exist
*
* @param {string} name - relation name
* @param {string} [value] - relation value (noteId)
- * @returns {Promise<void>}
*/
- async setRelation(name, value) { return await this.setAttribute(RELATION, name, value); }
+ setRelation(name, value) { return this.setAttribute(RELATION, name, value); }
/**
* Remove label name-value pair, if it exists.
*
* @param {string} name - label name
* @param {string} [value] - label value
- * @returns {Promise<void>}
*/
- async removeLabel(name, value) { return await this.removeAttribute(LABEL, name, value); }
+ removeLabel(name, value) { return this.removeAttribute(LABEL, name, value); }
/**
* Remove relation name-value pair, if it exists.
*
* @param {string} name - relation name
* @param {string} [value] - relation value (noteId)
- * @returns {Promise<void>}
*/
- async removeRelation(name, value) { return await this.removeAttribute(RELATION, name, value); }
+ removeRelation(name, value) { return this.removeAttribute(RELATION, name, value); }
/**
- * @return {Promise<string[]>} return list of all descendant noteIds of this note. Returning just noteIds because number of notes can be huge. Includes also this note's noteId
+ * @return {string[]} return list of all descendant noteIds of this note. Returning just noteIds because number of notes can be huge. Includes also this note's noteId
*/
- async getDescendantNoteIds() {
- return await sql.getColumn(`
+ getDescendantNoteIds() {
+ return sql.getColumn(`
WITH RECURSIVE
tree(noteId) AS (
SELECT ?
@@ -768,9 +747,9 @@ class Note extends Entity {
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
* @param {string} [value] - attribute value
- * @returns {Promise<Note[]>}
+ * @returns {Note[]}
*/
- async getDescendantNotesWithAttribute(type, name, value) {
+ getDescendantNotesWithAttribute(type, name, value) {
const params = [this.noteId, name];
let valueCondition = "";
@@ -779,7 +758,7 @@ class Note extends Entity {
valueCondition = " AND attributes.value = ?";
}
- const notes = await repository.getEntities(`
+ const notes = this.repository.getEntities(`
WITH RECURSIVE
tree(noteId) AS (
SELECT ?
@@ -806,36 +785,36 @@ class Note extends Entity {
*
* @param {string} name - label name
* @param {string} [value] - label value
- * @returns {Promise<Note[]>}
+ * @returns {Note[]}
*/
- async getDescendantNotesWithLabel(name, value) { return await this.getDescendantNotesWithAttribute(LABEL, name, value); }
+ getDescendantNotesWithLabel(name, value) { return this.getDescendantNotesWithAttribute(LABEL, name, value); }
/**
* Finds descendant notes with given relation name and value. Only own relations are considered, not inherited ones
*
* @param {string} name - relation name
* @param {string} [value] - relation value
- * @returns {Promise<Note[]>}
+ * @returns {Note[]}
*/
- async getDescendantNotesWithRelation(name, value) { return await this.getDescendantNotesWithAttribute(RELATION, name, value); }
+ getDescendantNotesWithRelation(name, value) { return this.getDescendantNotesWithAttribute(RELATION, name, value); }
/**
* Returns note revisions of this note.
*
- * @returns {Promise<NoteRevision[]>}
+ * @returns {NoteRevision[]}
*/
- async getRevisions() {
- return await repository.getEntities("SELECT * FROM note_revisions WHERE noteId = ?", [this.noteId]);
+ getRevisions() {
+ return this.repository.getEntities("SELECT * FROM note_revisions WHERE noteId = ?", [this.noteId]);
}
/**
* Get list of links coming out of this note.
*
* @deprecated - not intended for general use
- * @returns {Promise<Attribute[]>}
+ * @returns {Attribute[]}
*/
- async getLinks() {
- return await repository.getEntities(`
+ getLinks() {
+ return this.repository.getEntities(`
SELECT *
FROM attributes
WHERE noteId = ? AND
@@ -845,24 +824,24 @@ class Note extends Entity {
}
/**
- * @returns {Promise<Branch[]>}
+ * @returns {Branch[]}
*/
- async getBranches() {
- return await repository.getEntities("SELECT * FROM branches WHERE isDeleted = 0 AND noteId = ?", [this.noteId]);
+ getBranches() {
+ return this.repository.getEntities("SELECT * FROM branches WHERE isDeleted = 0 AND noteId = ?", [this.noteId]);
}
/**
* @returns {boolean} - true if note has children
*/
- async hasChildren() {
- return (await this.getChildNotes()).length > 0;
+ hasChildren() {
+ return (this.getChildNotes()).length > 0;
}
/**
- * @returns {Promise<Note[]>} child notes of this note
+ * @returns {Note[]} child notes of this note
*/
- async getChildNotes() {
- return await repository.getEntities(`
+ getChildNotes() {
+ return this.repository.getEntities(`
SELECT notes.*
FROM branches
JOIN notes USING(noteId)
@@ -873,10 +852,10 @@ class Note extends Entity {
}
/**
- * @returns {Promise<Branch[]>} child branches of this note
+ * @returns {Branch[]} child branches of this note
*/
- async getChildBranches() {
- return await repository.getEntities(`
+ getChildBranches() {
+ return this.repository.getEntities(`
SELECT branches.*
FROM branches
WHERE branches.isDeleted = 0
@@ -885,10 +864,10 @@ class Note extends Entity {
}
/**
- * @returns {Promise<Note[]>} parent notes of this note (note can have multiple parents because of cloning)
+ * @returns {Note[]} parent notes of this note (note can have multiple parents because of cloning)
*/
- async getParentNotes() {
- return await repository.getEntities(`
+ getParentNotes() {
+ return this.repository.getEntities(`
SELECT parent_notes.*
FROM
branches AS child_tree
@@ -899,17 +878,17 @@ class Note extends Entity {
}
/**
- * @return {Promise<string[][]>} - array of notePaths (each represented by array of noteIds constituting the particular note path)
+ * @return {string[][]} - array of notePaths (each represented by array of noteIds constituting the particular note path)
*/
- async getAllNotePaths() {
+ getAllNotePaths() {
if (this.noteId === 'root') {
return [['root']];
}
const notePaths = [];
- for (const parentNote of await this.getParentNotes()) {
- for (const parentPath of await parentNote.getAllNotePaths()) {
+ for (const parentNote of this.getParentNotes()) {
+ for (const parentPath of parentNote.getAllNotePaths()) {
parentPath.push(this.noteId);
notePaths.push(parentPath);
}
@@ -918,12 +897,22 @@ class Note extends Entity {
return notePaths;
}
+ getRelationDefinitions() {
+ return this.getLabels()
+ .filter(l => l.name.startsWith("relation:"));
+ }
+
+ getLabelDefinitions() {
+ return this.getLabels()
+ .filter(l => l.name.startsWith("relation:"));
+ }
+
/**
* @param ancestorNoteId
- * @return {Promise<boolean>} - true if ancestorNoteId occurs in at least one of the note's paths
+ * @return {boolean} - true if ancestorNoteId occurs in at least one of the note's paths
*/
- async isDescendantOfNote(ancestorNoteId) {
- const notePaths = await this.getAllNotePaths();
+ isDescendantOfNote(ancestorNoteId) {
+ const notePaths = this.getAllNotePaths();
return notePaths.some(path => path.includes(ancestorNoteId));
}
@@ -941,10 +930,6 @@ class Note extends Entity {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
- if (this.contentLength === undefined) {
- this.contentLength = -1;
- }
-
super.beforeSaving();
if (this.isChanged) {
@@ -974,7 +959,8 @@ class Note extends Entity {
}
}
-module.exports = Note;
+module.exports = Note;
+
@@ -990,7 +976,7 @@ module.exports = Note;
diff --git a/docs/backend_api/entities_note_revision.js.html b/docs/backend_api/entities_note_revision.js.html
index 3fddcc676..e1f1a4214 100644
--- a/docs/backend_api/entities_note_revision.js.html
+++ b/docs/backend_api/entities_note_revision.js.html
@@ -30,11 +30,10 @@
const Entity = require('./entity');
const protectedSessionService = require('../services/protected_session');
-const repository = require('../services/repository');
const utils = require('../services/utils');
const sql = require('../services/sql');
const dateUtils = require('../services/date_utils');
-const syncTableService = require('../services/sync_table');
+const entityChangesService = require('../services/entity_changes.js');
/**
* NoteRevision represents snapshot of note's title and content at some point in the past. It's used for seamless note versioning.
@@ -44,7 +43,6 @@ const syncTableService = require('../services/sync_table');
* @property {string} type
* @property {string} mime
* @property {string} title
- * @property {int} contentLength
* @property {boolean} isErased
* @property {boolean} isProtected
* @property {string} dateLastEdited
@@ -58,11 +56,12 @@ const syncTableService = require('../services/sync_table');
class NoteRevision extends Entity {
static get entityName() { return "note_revisions"; }
static get primaryKeyName() { return "noteRevisionId"; }
- static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "contentLength", "isErased", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; }
+ static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "isErased", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; }
constructor(row) {
super(row);
+ this.isErased = !!this.isErased;
this.isProtected = !!this.isProtected;
if (this.isProtected) {
@@ -75,8 +74,8 @@ class NoteRevision extends Entity {
}
}
- async getNote() {
- return await repository.getNote(this.noteId);
+ getNote() {
+ return this.repository.getNote(this.noteId);
}
/** @returns {boolean} true if the note has string content (not binary) */
@@ -93,10 +92,10 @@ class NoteRevision extends Entity {
* This is the same approach as is used for Note's content.
*/
- /** @returns {Promise<*>} */
- async getContent(silentNotFoundError = false) {
+ /** @returns {*} */
+ getContent(silentNotFoundError = false) {
if (this.content === undefined) {
- const res = await sql.getRow(`SELECT content, hash FROM note_revision_contents WHERE noteRevisionId = ?`, [this.noteRevisionId]);
+ const res = sql.getRow(`SELECT content, hash FROM note_revision_contents WHERE noteRevisionId = ?`, [this.noteRevisionId]);
if (!res) {
if (silentNotFoundError) {
@@ -129,13 +128,7 @@ class NoteRevision extends Entity {
}
}
- /** @returns {Promise} */
- async setContent(content) {
- // force updating note itself so that utcDateModified is represented correctly even for the content
- this.forcedChange = true;
- this.contentLength = content === null ? 0 : content.length;
- await this.save();
-
+ setContent(content) {
this.content = content;
const pojo = {
@@ -154,9 +147,9 @@ class NoteRevision extends Entity {
}
}
- await sql.upsert("note_revision_contents", "noteRevisionId", pojo);
+ sql.upsert("note_revision_contents", "noteRevisionId", pojo);
- await syncTableService.addNoteRevisionContentSync(this.noteRevisionId);
+ entityChangesService.addNoteRevisionContentEntityChange(this.noteRevisionId);
}
beforeSaving() {
@@ -183,7 +176,8 @@ class NoteRevision extends Entity {
}
}
-module.exports = NoteRevision;
+module.exports = NoteRevision;
+
@@ -199,7 +193,7 @@ module.exports = NoteRevision;
diff --git a/docs/backend_api/entities_option.js.html b/docs/backend_api/entities_option.js.html
index b8f1dbd93..255779f2f 100644
--- a/docs/backend_api/entities_option.js.html
+++ b/docs/backend_api/entities_option.js.html
@@ -82,7 +82,7 @@ module.exports = Option;
diff --git a/docs/backend_api/entities_recent_note.js.html b/docs/backend_api/entities_recent_note.js.html
index 510c9a666..a24776e2d 100644
--- a/docs/backend_api/entities_recent_note.js.html
+++ b/docs/backend_api/entities_recent_note.js.html
@@ -75,7 +75,7 @@ module.exports = RecentNote;
diff --git a/docs/backend_api/global.html b/docs/backend_api/global.html
index a060ec36e..a5e851b1e 100644
--- a/docs/backend_api/global.html
+++ b/docs/backend_api/global.html
@@ -391,7 +391,7 @@
- Source:
@@ -579,7 +579,7 @@
- Source:
@@ -767,7 +767,7 @@
- Source:
@@ -1053,7 +1053,7 @@
- Source:
@@ -1089,7 +1089,7 @@
diff --git a/docs/backend_api/index.html b/docs/backend_api/index.html
index df34aab26..4051b8b8f 100644
--- a/docs/backend_api/index.html
+++ b/docs/backend_api/index.html
@@ -56,7 +56,7 @@
diff --git a/docs/backend_api/services_backend_script_api.js.html b/docs/backend_api/services_backend_script_api.js.html
index caa3973a9..0fef95946 100644
--- a/docs/backend_api/services_backend_script_api.js.html
+++ b/docs/backend_api/services_backend_script_api.js.html
@@ -38,9 +38,9 @@ const repository = require('./repository');
const axios = require('axios');
const dayjs = require('dayjs');
const cloningService = require('./cloning');
-const ws = require('./ws.js');
const appInfo = require('./app_info');
-const searchService = require('./search');
+const searchService = require('./search/services/search');
+const SearchContext = require("./search/search_context.js");
/**
* This is the main backend API interface for scripts. It's published in the local "api" object.
@@ -78,38 +78,31 @@ function BackendScriptApi(currentNote, apiParams) {
/**
* @method
* @param {string} noteId
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
this.getNote = repository.getNote;
/**
* @method
* @param {string} branchId
- * @returns {Promise<Branch|null>}
+ * @returns {Branch|null}
*/
this.getBranch = repository.getBranch;
/**
* @method
* @param {string} attributeId
- * @returns {Promise<Attribute|null>}
+ * @returns {Attribute|null}
*/
this.getAttribute = repository.getAttribute;
- /**
- * @method
- * @param {string} imageId
- * @returns {Promise<Image|null>}
- */
- this.getImage = repository.getImage;
-
/**
* Retrieves first entity from the SQL's result set.
*
* @method
* @param {string} SQL query
* @param {Array.<?>} array of params
- * @returns {Promise<Entity|null>}
+ * @returns {Entity|null}
*/
this.getEntity = repository.getEntity;
@@ -117,30 +110,38 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
* @param {string} SQL query
* @param {Array.<?>} array of params
- * @returns {Promise<Entity[]>}
+ * @returns {Entity[]}
*/
this.getEntities = repository.getEntities;
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
- * "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
+ * "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
*
* @method
- * @param {string} searchString
- * @returns {Promise<Note[]>}
+ * @param {string} query
+ * @param {SearchContext} [searchContext]
+ * @returns {Note[]}
*/
- this.searchForNotes = searchService.searchForNotes;
+ this.searchForNotes = (query, searchContext) => {
+ searchContext = searchContext || new SearchContext();
+
+ const noteIds = searchService.findNotesWithQuery(query, searchContext)
+ .map(sr => sr.noteId);
+
+ return repository.getNotes(noteIds);
+ };
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
- * "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
+ * "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
*
* @method
* @param {string} searchString
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
- this.searchForNote = async searchString => {
- const notes = await searchService.searchForNotes(searchString);
+ this.searchForNote = searchString => {
+ const notes = searchService.searchNoteEntities(searchString);
return notes.length > 0 ? notes[0] : null;
};
@@ -151,7 +152,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
* @param {string} name - attribute name
* @param {string} [value] - attribute value
- * @returns {Promise<Note[]>}
+ * @returns {Note[]}
*/
this.getNotesWithLabel = attributeService.getNotesWithLabel;
@@ -161,7 +162,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
* @param {string} name - attribute name
* @param {string} [value] - attribute value
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
this.getNoteWithLabel = attributeService.getNoteWithLabel;
@@ -172,7 +173,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @param {string} noteId
* @param {string} parentNoteId
* @param {string} prefix - if branch will be create between note and parent note, set this prefix
- * @returns {Promise<void>}
+ * @returns {void}
*/
this.ensureNoteIsPresentInParent = cloningService.ensureNoteIsPresentInParent;
@@ -182,7 +183,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
* @param {string} noteId
* @param {string} parentNoteId
- * @returns {Promise<void>}
+ * @returns {void}
*/
this.ensureNoteIsAbsentFromParent = cloningService.ensureNoteIsAbsentFromParent;
@@ -194,7 +195,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @param {string} noteId
* @param {string} parentNoteId
* @param {string} prefix - if branch will be create between note and parent note, set this prefix
- * @returns {Promise<void>}
+ * @returns {void}
*/
this.toggleNoteInParent = cloningService.toggleNoteInParent;
@@ -211,9 +212,9 @@ function BackendScriptApi(currentNote, apiParams) {
* @param {string} parentNoteId
* @param {string} title
* @param {string} content
- * @return {Promise<{note: Note, branch: Branch}>}
+ * @return {{note: Note, branch: Branch}}
*/
- this.createTextNote = async (parentNoteId, title, content = '') => await noteService.createNewNote({
+ this.createTextNote = (parentNoteId, title, content = '') => noteService.createNewNote({
parentNoteId,
title,
content,
@@ -227,9 +228,9 @@ function BackendScriptApi(currentNote, apiParams) {
* @param {string} parentNoteId
* @param {string} title
* @param {object} content
- * @return {Promise<{note: Note, branch: Branch}>}
+ * @return {{note: Note, branch: Branch}}
*/
- this.createDataNote = async (parentNoteId, title, content = {}) => await noteService.createNewNote({
+ this.createDataNote = (parentNoteId, title, content = {}) => noteService.createNewNote({
parentNoteId,
title,
content: JSON.stringify(content, null, '\t'),
@@ -254,7 +255,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
*
* @param {CreateNewNoteParams} [params]
- * @returns {Promise<{note: Note, branch: Branch}>} object contains newly created entities note and branch
+ * @returns {{note: Note, branch: Branch}} object contains newly created entities note and branch
*/
this.createNewNote = noteService.createNewNote;
@@ -276,19 +277,19 @@ function BackendScriptApi(currentNote, apiParams) {
/**
* @method
- * @deprecated please use createNote() API method instead
+ * @deprecated please use createNewNote() API method instead
*
* @param {string} parentNoteId - create new note under this parent
* @param {string} title
* @param {string} [content=""]
* @param {CreateNoteExtraOptions} [extraOptions={}]
- * @returns {Promise<{note: Note, branch: Branch}>} object contains newly created entities note and branch
+ * @returns {{note: Note, branch: Branch}} object contains newly created entities note and branch
*/
- this.createNote = async (parentNoteId, title, content = "", extraOptions= {}) => {
+ this.createNote = (parentNoteId, title, content = "", extraOptions= {}) => {
extraOptions.parentNoteId = parentNoteId;
extraOptions.title = title;
- const parentNote = await repository.getNote(parentNoteId);
+ const parentNote = repository.getNote(parentNoteId);
// code note type can be inherited, otherwise text is default
extraOptions.type = parentNote.type === 'code' ? 'code' : 'text';
@@ -303,19 +304,21 @@ function BackendScriptApi(currentNote, apiParams) {
extraOptions.content = content;
}
- const {note, branch} = await noteService.createNewNote(extraOptions);
-
- for (const attr of extraOptions.attributes || []) {
- await attributeService.createAttribute({
- noteId: note.noteId,
- type: attr.type,
- name: attr.name,
- value: attr.value,
- isInheritable: !!attr.isInheritable
- });
- }
-
- return {note, branch};
+ return sql.transactional(() => {
+ const {note, branch} = noteService.createNewNote(extraOptions);
+
+ for (const attr of extraOptions.attributes || []) {
+ attributeService.createAttribute({
+ noteId: note.noteId,
+ type: attr.type,
+ name: attr.name,
+ value: attr.value,
+ isInheritable: !!attr.isInheritable
+ });
+ }
+
+ return {note, branch};
+ });
};
/**
@@ -329,7 +332,7 @@ function BackendScriptApi(currentNote, apiParams) {
* Returns root note of the calendar.
*
* @method
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
this.getRootCalendarNote = dateNoteService.getRootCalendarNote;
@@ -338,7 +341,7 @@ function BackendScriptApi(currentNote, apiParams) {
*
* @method
* @param {string} date in YYYY-MM-DD format
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
this.getDateNote = dateNoteService.getDateNote;
@@ -346,7 +349,7 @@ function BackendScriptApi(currentNote, apiParams) {
* Returns today's day note. If such note doesn't exist, it is created.
*
* @method
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
this.getTodayNote = dateNoteService.getTodayNote;
@@ -356,7 +359,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
* @param {string} date in YYYY-MM-DD format
* @param {object} options - "startOfTheWeek" - either "monday" (default) or "sunday"
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
this.getWeekNote = dateNoteService.getWeekNote;
@@ -365,7 +368,7 @@ function BackendScriptApi(currentNote, apiParams) {
*
* @method
* @param {string} date in YYYY-MM format
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
this.getMonthNote = dateNoteService.getMonthNote;
@@ -374,14 +377,13 @@ function BackendScriptApi(currentNote, apiParams) {
*
* @method
* @param {string} year in YYYY format
- * @returns {Promise<Note|null>}
+ * @returns {Note|null}
*/
this.getYearNote = dateNoteService.getYearNote;
/**
* @method
* @param {string} parentNoteId - this note's child notes will be sorted
- * @returns Promise<void>
*/
this.sortNotesAlphabetically = treeService.sortNotesAlphabetically;
@@ -403,12 +405,9 @@ function BackendScriptApi(currentNote, apiParams) {
* This functions wraps code which is supposed to be running in transaction. If transaction already
* exists, then we'll use that transaction.
*
- * This method is required only when script has label manualTransactionHandling, all other scripts are
- * transactional by default.
- *
* @method
* @param {function} func
- * @returns {Promise<?>} result of func callback
+ * @returns {?} result of func callback
*/
this.transactional = sql.transactional;
@@ -443,7 +442,7 @@ module.exports = BackendScriptApi;
diff --git a/docs/frontend_api/Branch.html b/docs/frontend_api/Branch.html
index f8a5d8573..a30e20eed 100644
--- a/docs/frontend_api/Branch.html
+++ b/docs/frontend_api/Branch.html
@@ -93,7 +93,7 @@
- Source:
@@ -661,7 +661,7 @@
- (async) getParentNote() → {NoteShort}
+ getNoteFromCache() → {NoteShort}
@@ -763,7 +763,7 @@
- isTopLevel() → {boolean}
+ (async) getParentNote() → {NoteShort}
@@ -836,6 +836,108 @@
+Returns:
+
+
+
+
+
+ -
+ Type
+
+ -
+
+NoteShort
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ isTopLevel() → {boolean}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Returns:
@@ -885,7 +987,7 @@
diff --git a/docs/frontend_api/FrontendScriptApi.html b/docs/frontend_api/FrontendScriptApi.html
index 4be267270..4cc250285 100644
--- a/docs/frontend_api/FrontendScriptApi.html
+++ b/docs/frontend_api/FrontendScriptApi.html
@@ -1556,7 +1556,7 @@
- Source:
@@ -1712,7 +1712,7 @@
- Source:
@@ -1892,7 +1892,7 @@
- Source:
@@ -2025,7 +2025,7 @@
- Source:
@@ -2131,7 +2131,7 @@
- Source:
@@ -2237,7 +2237,7 @@
- Source:
@@ -2391,7 +2391,7 @@
- Source:
@@ -2528,7 +2528,7 @@
- Source:
@@ -2635,7 +2635,7 @@ if some action needs to happen on only one specific instance.
- Source:
@@ -2790,7 +2790,7 @@ if some action needs to happen on only one specific instance.
- Source:
@@ -2946,7 +2946,7 @@ if some action needs to happen on only one specific instance.
- Source:
@@ -3147,7 +3147,7 @@ otherwise (by e.g. createNoteLink())
- Source:
@@ -3253,7 +3253,7 @@ otherwise (by e.g. createNoteLink())
- Source:
@@ -3408,7 +3408,7 @@ otherwise (by e.g. createNoteLink())
- Source:
@@ -3559,7 +3559,7 @@ otherwise (by e.g. createNoteLink())
- Source:
@@ -3667,7 +3667,7 @@ otherwise (by e.g. createNoteLink())
- Source:
@@ -3823,7 +3823,7 @@ otherwise (by e.g. createNoteLink())
- Source:
@@ -3979,7 +3979,139 @@ otherwise (by e.g. createNoteLink())
- Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ refreshIncludedNote(includedNoteId)
+
+
+
+
+
+
+
+ This will refresh all currently opened notes which have included note specified in the parameter
+
+
+
+
+
+
+
+
+
+
+ Parameters:
+
+
+
+
+
+
+ | Name |
+
+
+ Type |
+
+
+
+
+
+ Description |
+
+
+
+
+
+
+
+
+ includedNoteId |
+
+
+
+
+ |
+
+
+
+
+
+ noteId of the included note |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
@@ -4065,7 +4197,7 @@ otherwise (by e.g. createNoteLink())
- Source:
@@ -4202,7 +4334,7 @@ otherwise (by e.g. createNoteLink())
- Source:
@@ -4516,7 +4648,7 @@ Internally this serializes the anonymous function into string and sends it to ba
This is a powerful search method - you can search by attributes and their values, e.g.:
-"@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
+"#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
@@ -4609,7 +4741,7 @@ Internally this serializes the anonymous function into string and sends it to ba
- Source:
@@ -4672,7 +4804,7 @@ Internally this serializes the anonymous function into string and sends it to ba
This is a powerful search method - you can search by attributes and their values, e.g.:
-"@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
+"#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
@@ -4920,7 +5052,7 @@ Internally this serializes the anonymous function into string and sends it to ba
- Source:
@@ -5071,7 +5203,7 @@ Internally this serializes the anonymous function into string and sends it to ba
- Source:
@@ -5208,7 +5340,7 @@ Internally this serializes the anonymous function into string and sends it to ba
- Source:
@@ -5345,7 +5477,7 @@ Internally this serializes the anonymous function into string and sends it to ba
- Source:
@@ -5437,7 +5569,7 @@ Typical use case is when new note has been created, we should wait until it is s
- Source:
@@ -5489,7 +5621,7 @@ Typical use case is when new note has been created, we should wait until it is s
diff --git a/docs/frontend_api/NoteComplement.html b/docs/frontend_api/NoteComplement.html
index ae6edadd3..9475f6efa 100644
--- a/docs/frontend_api/NoteComplement.html
+++ b/docs/frontend_api/NoteComplement.html
@@ -93,7 +93,7 @@
- Source:
@@ -143,6 +143,122 @@
+combinedDateModified
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+combinedUtcDateModified
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
content
@@ -183,7 +299,65 @@
- Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+contentLength
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Source:
+
@@ -241,7 +415,7 @@
- Source:
@@ -299,7 +473,7 @@
- Source:
@@ -415,7 +589,7 @@
- Source:
@@ -473,7 +647,7 @@
- Source:
@@ -513,7 +687,7 @@
diff --git a/docs/frontend_api/NoteShort.html b/docs/frontend_api/NoteShort.html
index df31231ed..6ff10cc88 100644
--- a/docs/frontend_api/NoteShort.html
+++ b/docs/frontend_api/NoteShort.html
@@ -30,7 +30,9 @@
NoteShort(treeCache, row)
- This note's representation is used in note tree and is kept in TreeCache.
+ FIXME: since there's no "full note" anymore we can rename this to Note
+
+This note's representation is used in note tree and is kept in TreeCache.
@@ -165,7 +167,7 @@
- Source:
@@ -265,7 +267,7 @@
- Source:
@@ -333,7 +335,7 @@
- Source:
@@ -401,65 +403,7 @@
- Source:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-contentLength
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Source:
-
@@ -517,7 +461,7 @@
- Source:
@@ -575,7 +519,7 @@
- Source:
@@ -633,7 +577,7 @@
- Source:
@@ -691,7 +635,7 @@
- Source:
@@ -759,7 +703,7 @@
- Source:
@@ -827,7 +771,7 @@
- Source:
@@ -895,7 +839,7 @@
- Source:
@@ -953,7 +897,7 @@
- Source:
@@ -1011,7 +955,7 @@
- Source:
@@ -1159,7 +1103,7 @@
- Source:
@@ -1359,7 +1303,7 @@
- Source:
@@ -1537,7 +1481,7 @@
- Source:
@@ -1643,7 +1587,7 @@
- Source:
@@ -1745,7 +1689,7 @@
- Source:
@@ -1847,7 +1791,7 @@
- Source:
@@ -1949,7 +1893,7 @@
- Source:
@@ -2051,7 +1995,7 @@
- Source:
@@ -2202,7 +2146,7 @@
- Source:
@@ -2260,7 +2204,7 @@
- getLabelDefinitions(nameopt) → {Array.<Attribute>}
+ getLabels(nameopt) → {Array.<Attribute>}
@@ -2369,7 +2313,7 @@
- Source:
@@ -2398,7 +2342,7 @@
- all note's label definitions, including inherited ones
+ all note's labels (attributes with type label), including inherited ones
@@ -2427,7 +2371,7 @@
- getLabels(nameopt) → {Array.<Attribute>}
+ getLabelValue(name) → {string}
@@ -2455,8 +2399,6 @@
Type |
- Attributes |
-
@@ -2482,20 +2424,10 @@
-
-
- <optional>
-
-
-
-
-
- |
-
- label name to filter |
+ label name |
@@ -2536,7 +2468,7 @@
- Source:
@@ -2565,7 +2497,7 @@
- all note's labels (attributes with type label), including inherited ones
+ label value if label exists, null otherwise
@@ -2576,7 +2508,7 @@
-
-Array.<Attribute>
+string
@@ -2594,68 +2526,23 @@
- getLabelValue(name) → {string}
-
-
+ (async) getNoteComplement() → {Promise.<NoteComplement>}
-
-
-
-
-
-
-
-
-
-
- Parameters:
-
-
-
-
- | Name |
-
-
- Type |
-
-
-
- Description |
-
-
+
+ Return note complement which is most importantly note's content
+
-
-
-
-
- name |
-
-
-
-
-string
-
-
-
- |
-
-
- label name |
-
-
-
-
@@ -2691,7 +2578,7 @@
- Source:
@@ -2719,10 +2606,6 @@
Returns:
-
- label value if label exists, null otherwise
-
-
@@ -2731,7 +2614,7 @@
-
-string
+Promise.<NoteComplement>
@@ -2869,7 +2752,7 @@
- Source:
@@ -3069,7 +2952,7 @@
- Source:
@@ -3247,7 +3130,7 @@
- Source:
@@ -3402,7 +3285,7 @@
- Source:
@@ -3569,7 +3452,7 @@
- Source:
@@ -3724,7 +3607,7 @@
- Source:
@@ -3879,7 +3762,7 @@
- Source:
@@ -4046,7 +3929,7 @@
- Source:
@@ -4201,7 +4084,7 @@
- Source:
@@ -4307,7 +4190,7 @@
- Source:
@@ -4409,7 +4292,7 @@
- Source:
@@ -4560,7 +4443,7 @@
- Source:
@@ -4618,7 +4501,7 @@
- getRelationDefinitions(nameopt) → {Array.<Attribute>}
+ getRelations(nameopt) → {Array.<Attribute>}
@@ -4727,7 +4610,7 @@
- Source:
@@ -4756,7 +4639,7 @@
- all note's relation definitions including inherited ones
+ all note's relations (attributes with type relation), including inherited ones
@@ -4785,7 +4668,7 @@
- getRelations(nameopt) → {Array.<Attribute>}
+ (async) getRelationTarget(name) → {Promise.<NoteShort>|null}
@@ -4813,8 +4696,6 @@
Type |
- Attributes |
-
@@ -4840,20 +4721,10 @@
-
-
- <optional>
-
-
-
-
-
- |
-
- relation name to filter |
+ |
@@ -4894,7 +4765,7 @@
- Source:
@@ -4923,7 +4794,7 @@
- all note's relations (attributes with type relation), including inherited ones
+ target note of the relation or null (if target is empty or note was not found)
@@ -4934,7 +4805,10 @@
-
-Array.<Attribute>
+Promise.<NoteShort>
+|
+
+null
@@ -4952,7 +4826,7 @@
- (async) getRelationTarget(name) → {Promise.<NoteShort>|null}
+ (async) getRelationTargets(nameopt) → {Promise.<Array.<NoteShort>>}
@@ -4980,6 +4854,8 @@
Type |
+ Attributes |
+
@@ -5005,10 +4881,20 @@
+
+
+ <optional>
+
+
+
+
+ |
- |
+
+
+ relation name to filter |
@@ -5049,7 +4935,7 @@
- Source:
@@ -5077,10 +4963,6 @@
Returns:
-
- target note of the relation or null (if target is empty or note was not found)
-
-
@@ -5089,10 +4971,7 @@
-
-Promise.<NoteShort>
-|
-
-null
+Promise.<Array.<NoteShort>>
@@ -5110,7 +4989,7 @@
- (async) getRelationTargets(nameopt) → {Promise.<Array.<NoteShort>>}
+ getRelationValue(name) → {string}
@@ -5138,8 +5017,6 @@
Type |
- Attributes |
-
@@ -5165,20 +5042,10 @@
-
-
- <optional>
-
-
-
-
- |
-
-
- relation name to filter |
+ relation name |
@@ -5219,7 +5086,7 @@
- Source:
@@ -5247,6 +5114,10 @@
Returns:
+
+ relation value if relation exists, null otherwise
+
+
@@ -5255,7 +5126,7 @@
-
-Promise.<Array.<NoteShort>>
+string
@@ -5273,68 +5144,129 @@
- getRelationValue(name) → {string}
+ getTargetRelations() → {Array.<Attribute>}
+
+ Get relations which target this note
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- Parameters:
-
-
-
-
- | Name |
-
+
+ - Source:
+
+
- Type |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+
+
+ -
+ Type
+
+ -
+Array.<Attribute>
-
| Description |
-
-
-
+
+
+
-
-
- name |
-
-
-
-
-string
-
- |
+
-
+
- relation name |
-
+
+ (async) getTargetRelationSourceNotes() → {Array.<NoteShort>}
+
-
-
+
+
+
+
+ Get relations which target this note
+
+
+
+
+
+
+
+
@@ -5370,7 +5302,7 @@
- Source:
@@ -5398,10 +5330,6 @@
Returns:
-
- relation value if relation exists, null otherwise
-
-
@@ -5410,7 +5338,7 @@
-
-string
+Array.<NoteShort>
@@ -5428,17 +5356,13 @@
- getTargetRelations() → {Array.<Attribute>}
+ getTemplateNotes() → {Array.<NoteShort>}
-
- Get relations which target this note
-
-
@@ -5480,7 +5404,7 @@
- Source:
@@ -5516,7 +5440,7 @@
-
-Array.<Attribute>
+Array.<NoteShort>
@@ -5654,7 +5578,7 @@
- Source:
@@ -5760,7 +5684,7 @@
- Source:
@@ -5911,7 +5835,7 @@
- Source:
@@ -6089,7 +6013,7 @@
- Source:
@@ -6244,7 +6168,7 @@
- Source:
@@ -6399,7 +6323,7 @@
- Source:
@@ -6554,7 +6478,7 @@
- Source:
@@ -6665,7 +6589,7 @@ Cache is note instance scoped.
- Source:
@@ -6749,7 +6673,7 @@ Cache is note instance scoped.
- Source:
@@ -6819,7 +6743,7 @@ Cache is note instance scoped.
diff --git a/docs/frontend_api/entities_attribute.js.html b/docs/frontend_api/entities_attribute.js.html
index a74c256fb..a3f06a7d3 100644
--- a/docs/frontend_api/entities_attribute.js.html
+++ b/docs/frontend_api/entities_attribute.js.html
@@ -26,7 +26,9 @@
- class Attribute {
+ import promotedAttributeDefinitionParser from '../services/promoted_attribute_definition_parser.js';
+
+class Attribute {
constructor(treeCache, row) {
this.treeCache = treeCache;
@@ -47,29 +49,75 @@
/** @param {int} position */
this.position = row.position;
/** @param {boolean} isInheritable */
- this.isInheritable = row.isInheritable;
+ this.isInheritable = !!row.isInheritable;
}
/** @returns {NoteShort} */
- async getNote() {
- return await this.treeCache.getNote(this.noteId);
+ getNote() {
+ return this.treeCache.notes[this.noteId];
}
- get jsonValue() {
- try {
- return JSON.parse(this.value);
- }
- catch (e) {
- return null;
- }
+ get targetNoteId() { // alias
+ return this.type === 'relation' ? this.value : undefined;
+ }
+
+ get isAutoLink() {
+ return this.type === 'relation' && ['internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'].includes(this.name);
}
get toString() {
return `Attribute(attributeId=${this.attributeId}, type=${this.type}, name=${this.name}, value=${this.value})`;
}
+
+ /**
+ * @return {boolean} - returns true if this attribute has the potential to influence the note in the argument.
+ * That can happen in multiple ways:
+ * 1. attribute is owned by the note
+ * 2. attribute is owned by the template of the note
+ * 3. attribute is owned by some note's ancestor and is inheritable
+ */
+ isAffecting(affectedNote) {
+ if (!affectedNote) {
+ return false;
+ }
+
+ const attrNote = this.getNote();
+
+ if (!attrNote) {
+ // the note (owner of the attribute) is not even loaded into the cache so it should not affect anything else
+ return false;
+ }
+
+ const owningNotes = [affectedNote, ...affectedNote.getTemplateNotes()];
+
+ for (const owningNote of owningNotes) {
+ if (owningNote.noteId === attrNote.noteId) {
+ return true;
+ }
+ }
+
+ if (this.isInheritable) {
+ for (const owningNote of owningNotes) {
+ if (owningNote.hasAncestor(attrNote)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ isDefinition() {
+ return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:'));
+ }
+
+ getDefinition() {
+ return promotedAttributeDefinitionParser.parse(this.value);
+ }
}
-export default Attribute;
+export default Attribute;
+
@@ -85,7 +133,7 @@ export default Attribute;
diff --git a/docs/frontend_api/entities_branch.js.html b/docs/frontend_api/entities_branch.js.html
index f492aabbb..fa6795955 100644
--- a/docs/frontend_api/entities_branch.js.html
+++ b/docs/frontend_api/entities_branch.js.html
@@ -56,6 +56,11 @@ class Branch {
return this.treeCache.getNote(this.noteId);
}
+ /** @returns {NoteShort} */
+ getNoteFromCache() {
+ return this.treeCache.getNoteFromCache(this.noteId);
+ }
+
/** @returns {NoteShort} */
async getParentNote() {
return this.treeCache.getNote(this.parentNoteId);
@@ -87,7 +92,7 @@ export default Branch;
diff --git a/docs/frontend_api/entities_note_complement.js.html b/docs/frontend_api/entities_note_complement.js.html
index 75b9636e8..c2253b930 100644
--- a/docs/frontend_api/entities_note_complement.js.html
+++ b/docs/frontend_api/entities_note_complement.js.html
@@ -34,9 +34,14 @@ class NoteComplement {
/** @param {string} */
this.noteId = row.noteId;
- /** @param {string} */
+ /**
+ * @param {string} - can either contain the whole content (in e.g. string notes), only part (large text notes) or nothing at all (binary notes, images)
+ */
this.content = row.content;
+ /** @param {int} */
+ this.contentLength = row.contentLength;
+
/** @param {string} */
this.dateCreated = row.dateCreated;
@@ -48,10 +53,19 @@ class NoteComplement {
/** @param {string} */
this.utcDateModified = row.utcDateModified;
+
+ // "combined" date modified give larger out of note's and note_content's dateModified
+
+ /** @param {string} */
+ this.combinedDateModified = row.combinedDateModified;
+
+ /** @param {string} */
+ this.combinedUtcDateModified = row.combinedUtcDateModified;
}
}
-export default NoteComplement;
+export default NoteComplement;
+
@@ -67,7 +81,7 @@ export default NoteComplement;
diff --git a/docs/frontend_api/entities_note_short.js.html b/docs/frontend_api/entities_note_short.js.html
index 4f56dd9ce..71979c12e 100644
--- a/docs/frontend_api/entities_note_short.js.html
+++ b/docs/frontend_api/entities_note_short.js.html
@@ -28,13 +28,14 @@
import server from '../services/server.js';
import Attribute from './attribute.js';
+import noteAttributeCache from "../services/note_attribute_cache.js";
const LABEL = 'label';
-const LABEL_DEFINITION = 'label-definition';
const RELATION = 'relation';
-const RELATION_DEFINITION = 'relation-definition';
/**
+ * FIXME: since there's no "full note" anymore we can rename this to Note
+ *
* This note's representation is used in note tree and is kept in TreeCache.
*/
class NoteShort {
@@ -70,8 +71,6 @@ class NoteShort {
this.noteId = row.noteId;
/** @param {string} */
this.title = row.title;
- /** @param {int} */
- this.contentLength = row.contentLength;
/** @param {boolean} */
this.isProtected = !!row.isProtected;
/** @param {string} one of 'text', 'code', 'file' or 'render' */
@@ -83,6 +82,10 @@ class NoteShort {
}
addParent(parentNoteId, branchId) {
+ if (parentNoteId === 'none') {
+ return;
+ }
+
if (!this.parents.includes(parentNoteId)) {
this.parents.push(parentNoteId);
}
@@ -97,6 +100,10 @@ class NoteShort {
this.childToBranch[childNoteId] = branchId;
+ this.sortChildren();
+ }
+
+ sortChildren() {
const branchIdPos = {};
for (const branchId of Object.values(this.childToBranch)) {
@@ -184,9 +191,9 @@ class NoteShort {
getOwnedAttributes(type, name) {
const attrs = this.attributes
.map(attributeId => this.treeCache.attributes[attributeId])
- .filter(attr => !!attr);
+ .filter(Boolean); // filter out nulls;
- return this.__filterAttrs(attrs, type, name)
+ return this.__filterAttrs(attrs, type, name);
}
/**
@@ -195,48 +202,66 @@ class NoteShort {
* @returns {Attribute[]} all note's attributes, including inherited ones
*/
getAttributes(type, name) {
- const ownedAttributes = this.getOwnedAttributes();
+ return this.__filterAttrs(this.__getCachedAttributes([]), type, name);
+ }
- const attrArrs = [
- ownedAttributes
- ];
+ __getCachedAttributes(path) {
+ // notes/clones cannot form tree cycles, it is possible to create attribute inheritance cycle via templates
+ // when template instance is a parent of template itself
+ if (path.includes(this.noteId)) {
+ return [];
+ }
- for (const templateAttr of ownedAttributes.filter(oa => oa.type === 'relation' && oa.name === 'template')) {
- const templateNote = this.treeCache.getNoteFromCache(templateAttr.value);
+ if (!(this.noteId in noteAttributeCache.attributes)) {
+ const newPath = [...path, this.noteId];
+ const attrArrs = [ this.getOwnedAttributes() ];
- if (templateNote) {
- attrArrs.push(templateNote.getAttributes());
+ if (this.noteId !== 'root') {
+ for (const parentNote of this.getParentNotes()) {
+ // these virtual parent-child relationships are also loaded into frontend tree cache
+ if (parentNote.type !== 'search') {
+ attrArrs.push(parentNote.__getInheritableAttributes(newPath));
+ }
+ }
}
- }
- if (this.noteId !== 'root') {
- for (const parentNote of this.getParentNotes()) {
- // these virtual parent-child relationships are also loaded into frontend tree cache
- if (parentNote.type !== 'search') {
- attrArrs.push(parentNote.getInheritableAttributes());
+ for (const templateAttr of attrArrs.flat().filter(attr => attr.type === 'relation' && attr.name === 'template')) {
+ const templateNote = this.treeCache.notes[templateAttr.value];
+
+ if (templateNote && templateNote.noteId !== this.noteId) {
+ attrArrs.push(templateNote.__getCachedAttributes(newPath));
}
}
- }
- const attributes = attrArrs.flat();
+ noteAttributeCache.attributes[this.noteId] = [];
+ const addedAttributeIds = new Set();
+
+ for (const attr of attrArrs.flat()) {
+ if (!addedAttributeIds.has(attr.attributeId)) {
+ addedAttributeIds.add(attr.attributeId);
- return this.__filterAttrs(attributes, type, name);
+ noteAttributeCache.attributes[this.noteId].push(attr);
+ }
+ }
+ }
+
+ return noteAttributeCache.attributes[this.noteId];
}
__filterAttrs(attributes, type, name) {
- if (type && name) {
+ if (!type && !name) {
+ return attributes;
+ } else if (type && name) {
return attributes.filter(attr => attr.type === type && attr.name === name);
} else if (type) {
return attributes.filter(attr => attr.type === type);
} else if (name) {
return attributes.filter(attr => attr.name === name);
- } else {
- return attributes;
}
}
- getInheritableAttributes() {
- const attrs = this.getAttributes();
+ __getInheritableAttributes(path) {
+ const attrs = this.__getCachedAttributes(path);
return attrs.filter(attr => attr.isInheritable);
}
@@ -257,14 +282,6 @@ class NoteShort {
return this.getAttributes(LABEL, name);
}
- /**
- * @param {string} [name] - label name to filter
- * @returns {Attribute[]} all note's label definitions, including inherited ones
- */
- getLabelDefinitions(name) {
- return this.getAttributes(LABEL_DEFINITION, name);
- }
-
/**
* @param {string} [name] - relation name to filter
* @returns {Attribute[]} all note's relations (attributes with type relation), including inherited ones
@@ -281,14 +298,6 @@ class NoteShort {
return this.getAttributes(RELATION, name);
}
- /**
- * @param {string} [name] - relation name to filter
- * @returns {Attribute[]} all note's relation definitions including inherited ones
- */
- getRelationDefinitions(name) {
- return this.getAttributes(RELATION_DEFINITION, name);
- }
-
/**
* @param {string} type - attribute type (label, relation, etc.)
* @param {string} name - attribute name
@@ -448,6 +457,35 @@ class NoteShort {
return targets;
}
+ /**
+ * @returns {NoteShort[]}
+ */
+ getTemplateNotes() {
+ const relations = this.getRelations('template');
+
+ return relations.map(rel => this.treeCache.notes[rel.value]);
+ }
+
+ hasAncestor(ancestorNote) {
+ if (this.noteId === ancestorNote.noteId) {
+ return true;
+ }
+
+ for (const templateNote of this.getTemplateNotes()) {
+ if (templateNote.hasAncestor(ancestorNote)) {
+ return true;
+ }
+ }
+
+ for (const parentNote of this.getParentNotes()) {
+ if (parentNote.hasAncestor(ancestorNote)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* Clear note's attributes cache to force fresh reload for next attribute request.
* Cache is note instance scoped.
@@ -466,6 +504,26 @@ class NoteShort {
.map(attributeId => this.treeCache.attributes[attributeId]);
}
+ /**
+ * Get relations which target this note
+ *
+ * @returns {NoteShort[]}
+ */
+ async getTargetRelationSourceNotes() {
+ const targetRelations = this.getTargetRelations();
+
+ return await this.treeCache.getNotes(targetRelations.map(tr => tr.noteId));
+ }
+
+ /**
+ * Return note complement which is most importantly note's content
+ *
+ * @return {Promise<NoteComplement>}
+ */
+ async getNoteComplement() {
+ return await this.treeCache.getNoteComplement(this.noteId);
+ }
+
get toString() {
return `Note(noteId=${this.noteId}, title=${this.title})`;
}
@@ -483,7 +541,8 @@ class NoteShort {
}
}
-export default NoteShort;
+export default NoteShort;
+
@@ -499,7 +558,7 @@ export default NoteShort;
diff --git a/docs/frontend_api/global.html b/docs/frontend_api/global.html
index 6525a2d09..1be03111a 100644
--- a/docs/frontend_api/global.html
+++ b/docs/frontend_api/global.html
@@ -608,7 +608,7 @@ separately but should behave uniformly for the user.
diff --git a/docs/frontend_api/index.html b/docs/frontend_api/index.html
index 978ebed4f..d72750442 100644
--- a/docs/frontend_api/index.html
+++ b/docs/frontend_api/index.html
@@ -56,7 +56,7 @@
diff --git a/docs/frontend_api/services_frontend_script_api.js.html b/docs/frontend_api/services_frontend_script_api.js.html
index 0d32d82ba..4e20f4e31 100644
--- a/docs/frontend_api/services_frontend_script_api.js.html
+++ b/docs/frontend_api/services_frontend_script_api.js.html
@@ -95,7 +95,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* @return {Promise<void>}
*/
this.activateNewNote = async notePath => {
- await ws.waitForMaxKnownSyncId();
+ await ws.waitForMaxKnownEntityChangeId();
await appContext.tabManager.getActiveTabContext().setNote(notePath);
appContext.triggerEvent('focusAndSelectTitle');
@@ -115,7 +115,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
* @param {ToolbarButtonOptions} opts
*/
this.addButtonToToolbar = opts => {
- const buttonId = "toolbar-button-" + opts.title.replace(/[^a-zA-Z0-9]/g, "-");
+ const buttonId = "toolbar-button-" + opts.title.replace(/\s/g, "-");
const button = $('<button>')
.addClass("btn btn-sm")
@@ -180,7 +180,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
if (ret.success) {
// wait until all the changes done in the script has been synced to frontend before continuing
- await ws.waitForSyncId(ret.maxSyncId);
+ await ws.waitForEntityChangeId(ret.maxEntityChangeId);
return ret.executionResult;
}
@@ -197,25 +197,23 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
- * "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
+ * "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
*
* @method
* @param {string} searchString
* @returns {Promise<NoteShort[]>}
*/
this.searchForNotes = async searchString => {
- const noteIds = await this.runOnServer(async searchString => {
- const notes = await api.searchForNotes(searchString);
-
- return notes.map(note => note.noteId);
- }, [searchString]);
+ const noteIds = await this.runOnBackend(
+ searchString => api.searchForNotes(searchString).map(note => note.noteId),
+ [searchString]);
return await treeCache.getNotes(noteIds);
};
/**
* This is a powerful search method - you can search by attributes and their values, e.g.:
- * "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
+ * "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
*
* @method
* @param {string} searchString
@@ -430,10 +428,18 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
*
* @method
*/
- this.waitUntilSynced = ws.waitForMaxKnownSyncId;
+ this.waitUntilSynced = ws.waitForMaxKnownEntityChangeId;
+
+ /**
+ * This will refresh all currently opened notes which have included note specified in the parameter
+ *
+ * @param includedNoteId - noteId of the included note
+ */
+ this.refreshIncludedNote = includedNoteId => appContext.triggerEvent('refreshIncludedNote', {noteId: includedNoteId});
}
-export default FrontendScriptApi;
+export default FrontendScriptApi;
+
@@ -449,7 +455,7 @@ export default FrontendScriptApi;
diff --git a/docs/frontend_api/widgets_collapsible_widget.js.html b/docs/frontend_api/widgets_collapsible_widget.js.html
index e5ec10b7b..eb09e089e 100644
--- a/docs/frontend_api/widgets_collapsible_widget.js.html
+++ b/docs/frontend_api/widgets_collapsible_widget.js.html
@@ -57,12 +57,14 @@ export default class CollapsibleWidget extends TabAwareWidget {
doRender() {
this.$widget = $(WIDGET_TPL);
+ this.contentSized();
this.$widget.find('[data-target]').attr('data-target', "#" + this.componentId);
this.$bodyWrapper = this.$widget.find('.body-wrapper');
this.$bodyWrapper.attr('id', this.componentId); // for toggle to work we need id
- this.widgetName = this.constructor.name;
+ // not using constructor name because of webpack mangling class names ...
+ this.widgetName = this.widgetTitle.replace(/[^[a-zA-Z0-9]/g, "_");
if (!options.is(this.widgetName + 'Collapsed')) {
this.$bodyWrapper.collapse("show");
@@ -97,8 +99,6 @@ export default class CollapsibleWidget extends TabAwareWidget {
this.initialized = this.doRenderBody();
this.decorateWidget();
-
- return this.$widget;
}
saveCollapsed(collapse) {
@@ -126,7 +126,8 @@ export default class CollapsibleWidget extends TabAwareWidget {
isExpanded() {
return this.$bodyWrapper.hasClass("show");
}
-}
+}
+
@@ -142,7 +143,7 @@ export default class CollapsibleWidget extends TabAwareWidget {
diff --git a/src/services/backend_script_api.js b/src/services/backend_script_api.js
index f649fdaac..27f20fe6d 100644
--- a/src/services/backend_script_api.js
+++ b/src/services/backend_script_api.js
@@ -249,7 +249,7 @@ function BackendScriptApi(currentNote, apiParams) {
/**
* @method
- * @deprecated please use createNewNote() API method instead
+ * @deprecated please use createTextNote() with similar API for simpler use cases or createNewNote() for more complex needs
*
* @param {string} parentNoteId - create new note under this parent
* @param {string} title
|