@shaxpir/duiduidui-models 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dist/models/{content/ArrayView.d.ts → ArrayView.d.ts} +1 -1
  2. package/dist/models/{content/ArrayView.js → ArrayView.js} +14 -14
  3. package/dist/models/BayesianScore.d.ts +9 -0
  4. package/dist/models/BayesianScore.js +27 -0
  5. package/dist/models/{markup/ChangeModel.d.ts → ChangeModel.d.ts} +2 -3
  6. package/dist/models/{markup/ChangeModel.js → ChangeModel.js} +20 -10
  7. package/dist/models/{content/Content.d.ts → Content.d.ts} +9 -10
  8. package/dist/models/{content/Content.js → Content.js} +2 -6
  9. package/dist/models/{content/ContentKind.d.ts → ContentKind.d.ts} +3 -0
  10. package/dist/models/{content/ContentKind.js → ContentKind.js} +5 -1
  11. package/dist/models/{content/Device.d.ts → Device.d.ts} +15 -7
  12. package/dist/models/{content/Device.js → Device.js} +14 -18
  13. package/dist/models/Hanzi.d.ts +15 -0
  14. package/dist/models/{content/Manifest.d.ts → Manifest.d.ts} +7 -3
  15. package/dist/models/{content/Manifest.js → Manifest.js} +12 -8
  16. package/dist/models/{content/Media.d.ts → Media.d.ts} +2 -3
  17. package/dist/models/{content/Media.js → Media.js} +4 -5
  18. package/dist/models/{content/Metric.d.ts → Metric.d.ts} +2 -3
  19. package/dist/models/{content/Metric.js → Metric.js} +18 -20
  20. package/dist/models/{content/Model.d.ts → Model.d.ts} +3 -5
  21. package/dist/models/{content/Model.js → Model.js} +5 -6
  22. package/dist/models/{markup/Operation.d.ts → Operation.d.ts} +2 -5
  23. package/dist/models/{markup/Operation.js → Operation.js} +30 -25
  24. package/dist/models/Phrase.d.ts +39 -0
  25. package/dist/models/{content/Profile.d.ts → Profile.d.ts} +1 -2
  26. package/dist/models/{content/Profile.js → Profile.js} +7 -9
  27. package/dist/models/Progress.d.ts +26 -0
  28. package/dist/models/Progress.js +39 -0
  29. package/dist/models/Review.d.ts +14 -0
  30. package/dist/models/{content/Session.d.ts → Session.d.ts} +7 -15
  31. package/dist/models/Session.js +103 -0
  32. package/dist/models/Term.d.ts +36 -0
  33. package/dist/models/Term.js +82 -0
  34. package/dist/models/User.d.ts +32 -0
  35. package/dist/models/User.js +65 -0
  36. package/dist/models/Workspace.d.ts +37 -0
  37. package/dist/models/Workspace.js +94 -0
  38. package/dist/models/index.d.ts +22 -2
  39. package/dist/models/index.js +22 -2
  40. package/dist/repo/PermissiveJson1.d.ts +16 -16
  41. package/dist/repo/PermissiveJson1.js +17 -7
  42. package/dist/repo/ShareSync.d.ts +6 -6
  43. package/dist/repo/ShareSync.js +26 -19
  44. package/dist/repo/index.d.ts +1 -0
  45. package/dist/repo/index.js +1 -0
  46. package/dist/util/Encryption.d.ts +1 -1
  47. package/dist/util/index.d.ts +0 -6
  48. package/dist/util/index.js +0 -6
  49. package/lib/models/{content/ArrayView.ts → ArrayView.ts} +2 -2
  50. package/lib/models/BayesianScore.ts +32 -0
  51. package/lib/models/{markup/ChangeModel.ts → ChangeModel.ts} +3 -4
  52. package/lib/models/{content/Content.ts → Content.ts} +15 -18
  53. package/lib/models/{content/ContentKind.ts → ContentKind.ts} +6 -1
  54. package/lib/models/{content/Device.ts → Device.ts} +26 -22
  55. package/lib/models/Hanzi.ts +16 -0
  56. package/lib/models/{content/Manifest.ts → Manifest.ts} +15 -6
  57. package/lib/models/{content/Media.ts → Media.ts} +3 -4
  58. package/lib/models/Metric.ts +233 -0
  59. package/lib/models/{content/Model.ts → Model.ts} +4 -6
  60. package/lib/models/{markup/Operation.ts → Operation.ts} +6 -16
  61. package/lib/models/{content/Permissions.ts → Permissions.ts} +0 -2
  62. package/lib/models/Phrase.ts +53 -0
  63. package/lib/models/{content/Profile.ts → Profile.ts} +4 -6
  64. package/lib/models/Progress.ts +66 -0
  65. package/lib/models/Review.ts +18 -0
  66. package/lib/models/Session.ts +140 -0
  67. package/lib/models/Term.ts +139 -0
  68. package/lib/models/User.ts +97 -0
  69. package/lib/models/Workspace.ts +129 -0
  70. package/lib/models/index.ts +22 -2
  71. package/lib/repo/ShareSync.ts +9 -13
  72. package/lib/repo/index.ts +1 -0
  73. package/lib/util/Encryption.ts +1 -1
  74. package/lib/util/index.ts +0 -6
  75. package/package.json +4 -15
  76. package/dist/models/OutboundMessage.d.ts +0 -18
  77. package/dist/models/OutboundMessage.js +0 -25
  78. package/dist/models/content/Activity.d.ts +0 -10
  79. package/dist/models/content/Billing.d.ts +0 -144
  80. package/dist/models/content/Billing.js +0 -418
  81. package/dist/models/content/Book.d.ts +0 -77
  82. package/dist/models/content/Book.js +0 -407
  83. package/dist/models/content/Category.d.ts +0 -16
  84. package/dist/models/content/Category.js +0 -20
  85. package/dist/models/content/Checkpointable.d.ts +0 -21
  86. package/dist/models/content/Checkpointable.js +0 -156
  87. package/dist/models/content/Comment.d.ts +0 -19
  88. package/dist/models/content/Comment.js +0 -53
  89. package/dist/models/content/ConceptArt.d.ts +0 -31
  90. package/dist/models/content/ConceptArt.js +0 -84
  91. package/dist/models/content/Context.d.ts +0 -28
  92. package/dist/models/content/Context.js +0 -162
  93. package/dist/models/content/DevEnv.d.ts +0 -5
  94. package/dist/models/content/DevEnv.js +0 -9
  95. package/dist/models/content/Dictionary.d.ts +0 -31
  96. package/dist/models/content/Dictionary.js +0 -5
  97. package/dist/models/content/DictionaryEntry.d.ts +0 -20
  98. package/dist/models/content/DictionaryEntry.js +0 -2
  99. package/dist/models/content/ElasticModel.d.ts +0 -149
  100. package/dist/models/content/ElasticModel.js +0 -179
  101. package/dist/models/content/Environment.d.ts +0 -61
  102. package/dist/models/content/Environment.js +0 -124
  103. package/dist/models/content/ExportOptions.d.ts +0 -64
  104. package/dist/models/content/ExportOptions.js +0 -213
  105. package/dist/models/content/Folder.d.ts +0 -16
  106. package/dist/models/content/Folder.js +0 -33
  107. package/dist/models/content/Fragment.d.ts +0 -54
  108. package/dist/models/content/Fragment.js +0 -181
  109. package/dist/models/content/Hanzi.d.ts +0 -21
  110. package/dist/models/content/HighlightRule.d.ts +0 -9
  111. package/dist/models/content/HighlightRule.js +0 -2
  112. package/dist/models/content/Migration.d.ts +0 -68
  113. package/dist/models/content/Migration.js +0 -155
  114. package/dist/models/content/Phrase.d.ts +0 -8
  115. package/dist/models/content/Placeholder.d.ts +0 -8
  116. package/dist/models/content/Placeholder.js +0 -36
  117. package/dist/models/content/RichText.d.ts +0 -58
  118. package/dist/models/content/RichText.js +0 -79
  119. package/dist/models/content/Session.js +0 -173
  120. package/dist/models/content/Speech.d.ts +0 -67
  121. package/dist/models/content/Speech.js +0 -97
  122. package/dist/models/content/Stub.d.ts +0 -24
  123. package/dist/models/content/Stub.js +0 -179
  124. package/dist/models/content/Time.d.ts +0 -56
  125. package/dist/models/content/Time.js +0 -295
  126. package/dist/models/content/User.d.ts +0 -36
  127. package/dist/models/content/User.js +0 -95
  128. package/dist/models/content/Workspace.d.ts +0 -71
  129. package/dist/models/content/Workspace.js +0 -237
  130. package/dist/models/content/index.d.ts +0 -17
  131. package/dist/models/content/index.js +0 -34
  132. package/dist/models/legacy/LegacyBodyFormat.d.ts +0 -9
  133. package/dist/models/legacy/LegacyBodyFormat.js +0 -2
  134. package/dist/models/legacy/LegacyComment.d.ts +0 -12
  135. package/dist/models/legacy/LegacyComment.js +0 -2
  136. package/dist/models/legacy/LegacyContent.d.ts +0 -53
  137. package/dist/models/legacy/LegacyContent.js +0 -55
  138. package/dist/models/legacy/LegacyConversion.d.ts +0 -55
  139. package/dist/models/legacy/LegacyConversion.js +0 -401
  140. package/dist/models/legacy/LegacyFragment.d.ts +0 -21
  141. package/dist/models/legacy/LegacyFragment.js +0 -2
  142. package/dist/models/legacy/LegacyLocator.d.ts +0 -8
  143. package/dist/models/legacy/LegacyLocator.js +0 -31
  144. package/dist/models/legacy/LegacyOutboundMessage.d.ts +0 -16
  145. package/dist/models/legacy/LegacyOutboundMessage.js +0 -13
  146. package/dist/models/legacy/LegacyPicture.d.ts +0 -14
  147. package/dist/models/legacy/LegacyPicture.js +0 -2
  148. package/dist/models/legacy/LegacyProfile.d.ts +0 -9
  149. package/dist/models/legacy/LegacyProfile.js +0 -2
  150. package/dist/models/legacy/LegacySession.d.ts +0 -41
  151. package/dist/models/legacy/LegacySession.js +0 -35
  152. package/dist/models/legacy/LegacyStory.d.ts +0 -23
  153. package/dist/models/legacy/LegacyStory.js +0 -2
  154. package/dist/models/legacy/LegacyStub.d.ts +0 -15
  155. package/dist/models/legacy/LegacyStub.js +0 -2
  156. package/dist/models/legacy/LegacyTransaction.d.ts +0 -14
  157. package/dist/models/legacy/LegacyTransaction.js +0 -49
  158. package/dist/models/legacy/LegacyUser.d.ts +0 -28
  159. package/dist/models/legacy/LegacyUser.js +0 -32
  160. package/dist/models/legacy/LegacyWorkspace.d.ts +0 -23
  161. package/dist/models/legacy/LegacyWorkspace.js +0 -6
  162. package/dist/models/legacy/index.d.ts +0 -15
  163. package/dist/models/legacy/index.js +0 -32
  164. package/dist/models/markup/BodyFormat.d.ts +0 -14
  165. package/dist/models/markup/BodyFormat.js +0 -190
  166. package/dist/models/markup/DeltaOps.d.ts +0 -5
  167. package/dist/models/markup/DeltaOps.js +0 -74
  168. package/dist/models/markup/HtmlMarkup.d.ts +0 -4
  169. package/dist/models/markup/HtmlMarkup.js +0 -21
  170. package/dist/models/markup/index.d.ts +0 -4
  171. package/dist/models/markup/index.js +0 -21
  172. package/dist/util/Async.d.ts +0 -8
  173. package/dist/util/Async.js +0 -18
  174. package/dist/util/Base62.d.ts +0 -6
  175. package/dist/util/Base62.js +0 -47
  176. package/dist/util/BinarySearch.d.ts +0 -7
  177. package/dist/util/BinarySearch.js +0 -46
  178. package/dist/util/CachingHasher.d.ts +0 -8
  179. package/dist/util/CachingHasher.js +0 -41
  180. package/dist/util/Color.d.ts +0 -32
  181. package/dist/util/Color.js +0 -204
  182. package/dist/util/Dispatch.d.ts +0 -15
  183. package/dist/util/Dispatch.js +0 -79
  184. package/dist/util/EditDistance.d.ts +0 -13
  185. package/dist/util/EditDistance.js +0 -184
  186. package/dist/util/NumberFormat.d.ts +0 -14
  187. package/dist/util/NumberFormat.js +0 -224
  188. package/dist/util/Struct.d.ts +0 -4
  189. package/dist/util/Struct.js +0 -15
  190. package/dist/util/Template.d.ts +0 -16
  191. package/dist/util/Template.js +0 -128
  192. package/dist/util/Text.d.ts +0 -45
  193. package/dist/util/Text.js +0 -243
  194. package/dist/util/Tuples.d.ts +0 -9
  195. package/dist/util/Tuples.js +0 -135
  196. package/dist/util/Validate.d.ts +0 -4
  197. package/dist/util/Validate.js +0 -11
  198. package/dist/util/Vocabulary.d.ts +0 -3
  199. package/dist/util/Vocabulary.js +0 -35
  200. package/lib/models/content/Billing.ts +0 -558
  201. package/lib/models/content/DevEnv.ts +0 -5
  202. package/lib/models/content/DictionaryEntry.ts +0 -22
  203. package/lib/models/content/Hanzi.ts +0 -25
  204. package/lib/models/content/Phrase.ts +0 -10
  205. package/lib/models/content/Time.ts +0 -328
  206. package/lib/models/content/User.ts +0 -130
  207. package/lib/models/content/index.ts +0 -19
  208. package/lib/models/markup/DeltaOps.ts +0 -71
  209. package/lib/models/markup/index.ts +0 -6
  210. package/lib/util/Base62.ts +0 -47
  211. package/lib/util/CachingHasher.ts +0 -38
  212. package/lib/util/Dispatch.ts +0 -92
  213. package/lib/util/NumberFormat.ts +0 -194
  214. package/lib/util/Struct.ts +0 -14
  215. package/lib/util/Tuples.ts +0 -131
  216. /package/dist/models/{content/GeoLocation.d.ts → GeoLocation.d.ts} +0 -0
  217. /package/dist/models/{content/GeoLocation.js → GeoLocation.js} +0 -0
  218. /package/dist/models/{content/Hanzi.js → Hanzi.js} +0 -0
  219. /package/dist/models/{content/Permissions.d.ts → Permissions.d.ts} +0 -0
  220. /package/dist/models/{content/Permissions.js → Permissions.js} +0 -0
  221. /package/dist/models/{content/Phrase.js → Phrase.js} +0 -0
  222. /package/dist/models/{content/Activity.js → Review.js} +0 -0
  223. /package/dist/{models/markup → repo}/TextEditOps.d.ts +0 -0
  224. /package/dist/{models/markup → repo}/TextEditOps.js +0 -0
  225. /package/lib/models/{content/GeoLocation.ts → GeoLocation.ts} +0 -0
  226. /package/lib/{models/markup → repo}/TextEditOps.ts +0 -0
@@ -1,8 +1,7 @@
1
- import { Op as DeltaOp } from "@shaxpir/quill-delta";
1
+ import { Tuples } from "@shaxpir/shaxpir-common";
2
2
  import * as Changesets from 'json-diff-ts';
3
3
  import { Operation } from "json-diff-ts";
4
- import { Tuples } from "../../util/Tuples";
5
- import { Model } from "../content/Model";
4
+ import { Model } from "./Model";
6
5
 
7
6
  export interface ChangeItem {
8
7
  type:Operation;
@@ -15,7 +14,7 @@ export interface ModelChange {
15
14
  local:boolean;
16
15
  model:Model;
17
16
  items:ChangeItem[];
18
- op:DeltaOp[];
17
+ op:any[];
19
18
  }
20
19
 
21
20
  export class Changes {
@@ -1,16 +1,17 @@
1
1
  import { Doc } from '@shaxpir/sharedb/lib/client';
2
- import { ShareSync } from '../../repo/ShareSync';
3
- import { Struct } from '../../util/Struct';
4
- import { BillingPayload } from "./Billing";
2
+ import { CompactDateTime, MultiTime, Struct } from '@shaxpir/shaxpir-common';
3
+ import { ShareSync } from '../repo';
5
4
  import { ContentKind } from './ContentKind';
6
5
  import { DevicePayload } from './Device';
7
- import { HanziPayload } from './Hanzi';
6
+ import { MediaPayload } from './Media';
7
+ import { MetricPayload } from './Metric';
8
8
  import { Model } from './Model';
9
- import { PhrasePayload } from './Phrase';
10
9
  import { ProfilePayload } from "./Profile";
11
- import { CompactDateTime, MultiTime } from './Time';
10
+ import { ProgressPayload } from './Progress';
11
+ import { SessionPayload } from './Session';
12
+ import { TermPayload } from './Term';
12
13
  import { UserPayload } from './User';
13
- import { MediaPayload } from './Media';
14
+ import { WorkspacePayload } from './Workspace';
14
15
 
15
16
  enum ContentIdBrand {}
16
17
  enum ContentRefBrand {}
@@ -32,7 +33,6 @@ export interface ContentBody {
32
33
  export interface ContentMeta {
33
34
  ref:ContentRef;
34
35
  kind:ContentKind;
35
- is_head:boolean;
36
36
  id:ContentId;
37
37
  owner:ContentId;
38
38
  created_at:MultiTime;
@@ -40,13 +40,15 @@ export interface ContentMeta {
40
40
  }
41
41
 
42
42
  export type ContentPayload =
43
- BillingPayload
44
- | HanziPayload
45
- | PhrasePayload
46
- | DevicePayload
43
+ DevicePayload
47
44
  | MediaPayload
45
+ | MetricPayload
48
46
  | ProfilePayload
49
- | UserPayload;
47
+ | ProgressPayload
48
+ | SessionPayload
49
+ | TermPayload
50
+ | UserPayload
51
+ | WorkspacePayload;
50
52
 
51
53
  export abstract class Content extends Model {
52
54
 
@@ -56,11 +58,6 @@ export abstract class Content extends Model {
56
58
  super(doc, shouldAcquire, shareSync);
57
59
  }
58
60
 
59
- public get isHead():boolean {
60
- this.checkDisposed("Content.isHead");
61
- return this.meta.is_head;
62
- }
63
-
64
61
  public get meta():ContentMeta {
65
62
  this.checkDisposed("Content.meta");
66
63
  return this.doc.data.meta as ContentMeta;
@@ -1,13 +1,18 @@
1
1
  export enum ContentKind {
2
2
 
3
- // These are all the current Content subclasses
3
+ // No models yet for these, but they're definitely coming
4
4
  BILLING = "billing",
5
+
6
+ // These are all the current Content subclasses
5
7
  DEVICE = "device",
6
8
  METRIC = "metric",
7
9
  PROFILE = "profile",
10
+ PROGRESS = "progress",
8
11
  SESSION = "session",
12
+ TERM = "term",
9
13
  USER = "user",
10
14
  MEDIA = "media",
15
+ WORKSPACE = "workspace",
11
16
 
12
17
  // These are used in the ShareDB system, but for internal bookkeeping, not for Content subclasses.
13
18
  MANIFEST = "manifest",
@@ -1,17 +1,26 @@
1
1
  import { Doc } from '@shaxpir/sharedb/lib/client';
2
- import { ShareSync, ShareSyncFactory } from '../../repo/ShareSync';
3
- import { CachingHasher } from '../../util/CachingHasher';
4
- import { BatchOperation } from '../markup/Operation';
2
+ import { CompactDateTime, MultiClock } from "@shaxpir/shaxpir-common";
3
+ import { ShareSync, ShareSyncFactory } from '../repo';
5
4
  import { Content, ContentBody, ContentId, ContentMeta } from "./Content";
6
5
  import { ContentKind } from './ContentKind';
7
- import { CompactDateTime, MultiClock } from './Time';
6
+ import { BatchOperation } from './Operation';
8
7
 
9
8
  export interface LastSync {
10
- at_utc_time:CompactDateTime;
9
+ at_utc_time:CompactDateTime|null;
10
+ }
11
+
12
+ export interface TagFilterConfig {
13
+ any?: string[];
14
+ all?: string[];
15
+ none?: string[];
11
16
  }
12
17
 
13
18
  export interface DevicePayload {
14
19
  last_sync?:LastSync;
20
+ chinese_font?: string;
21
+ raw_search_text?: string;
22
+ star_filter?: boolean;
23
+ tag_filter?: TagFilterConfig;
15
24
  }
16
25
 
17
26
  export interface DeviceBody extends ContentBody {
@@ -21,23 +30,15 @@ export interface DeviceBody extends ContentBody {
21
30
 
22
31
  export class Device extends Content {
23
32
 
24
- public static makeProfleId(userId:ContentId):ContentId {
25
- return CachingHasher.makeMd5ContentId(userId + "-" + ContentKind.PROFILE);
26
- }
27
-
28
33
  public static create(
29
34
  userId:ContentId,
30
- deviceId:ContentId,
31
- theme:string,
32
- typeface:string,
33
- typesize:string
35
+ deviceId:ContentId
34
36
  ):Device {
35
37
  const now = MultiClock.now();
36
38
  return ShareSyncFactory.get().createContent(
37
39
  {
38
40
  meta : {
39
41
  ref : deviceId,
40
- is_head : true,
41
42
  kind : ContentKind.DEVICE,
42
43
  id : deviceId,
43
44
  owner : userId,
@@ -62,24 +63,27 @@ export class Device extends Content {
62
63
 
63
64
  public get lastSyncAtUtcTime():CompactDateTime {
64
65
  this.checkDisposed("Device.lastSyncAtUtcTime");
65
- this.ensureLastSyncAtUtcTimeExists();
66
- return this.payload.last_sync.at_utc_time;
66
+ return this.payload.last_sync.at_utc_time as CompactDateTime;
67
67
  }
68
68
  public setLastSyncAtUtcTime(value:CompactDateTime):void {
69
69
  this.checkDisposed("Device.setLastSyncAtUtcTime");
70
- this.ensureLastSyncAtUtcTimeExists();
71
70
  if (this.lastSyncAtUtcTime !== value) {
72
71
  const batch = new BatchOperation(this);
73
72
  batch.setPathValue([ 'payload', 'last_sync', 'at_utc_time' ] , value);
74
73
  batch.commit();
75
74
  }
76
75
  }
77
- private ensureLastSyncAtUtcTimeExists():void {
78
- this.checkDisposed("Device.ensureLastSyncAtUtcTimeExists");
79
- // If the 'last_sync' field doesn't exist, add it first...
80
- if (!this.payload.hasOwnProperty('last_sync')) {
76
+
77
+ public get chineseFont():string {
78
+ this.checkDisposed("Device.chineseFont");
79
+ return this.payload.chinese_font || 'Huninn';
80
+ }
81
+
82
+ public setChineseFont(value:string):void {
83
+ this.checkDisposed("Device.setChineseFont");
84
+ if (this.chineseFont !== value) {
81
85
  const batch = new BatchOperation(this);
82
- batch.setPathValue([ 'payload', 'last_sync' ] , { at_utc_time : null as CompactDateTime });
86
+ batch.setPathValue([ 'payload', 'chinese_font' ] , value);
83
87
  batch.commit();
84
88
  }
85
89
  }
@@ -0,0 +1,16 @@
1
+ export interface Hanzi {
2
+ text: string;
3
+ rank: number;
4
+ components: Array<{
5
+ text: string;
6
+ meaning: string;
7
+ pinyin: string;
8
+ }>;
9
+ radical: string;
10
+ radical_analysis: string;
11
+ component_analysis: string;
12
+ }
13
+
14
+ export interface BuiltInHanzi extends Hanzi {
15
+ id: number;
16
+ }
@@ -1,11 +1,10 @@
1
1
  import { Doc } from '@shaxpir/sharedb/lib/client';
2
- import { ShareSync, ShareSyncFactory } from '../../repo/ShareSync';
3
- import { CachingHasher } from '../../util/CachingHasher';
4
- import { BatchOperation } from "../markup/Operation";
2
+ import { CachingHasher, CompactDateTime, SingleTime, Time } from '@shaxpir/shaxpir-common';
3
+ import { ShareSync, ShareSyncFactory } from '../repo';
5
4
  import { Content, ContentId, ContentRef } from "./Content";
6
5
  import { ContentKind } from './ContentKind';
7
6
  import { Model } from './Model';
8
- import { CompactDateTime, SingleTime, Time } from './Time';
7
+ import { BatchOperation } from './Operation';
9
8
 
10
9
  export interface ManifestMeta {
11
10
  kind:ContentKind;
@@ -28,8 +27,13 @@ export interface ManifestEntry {
28
27
  export interface ManifestPayload {
29
28
  device:any;
30
29
  media:any;
30
+ metric:any;
31
31
  profile:any;
32
+ progress:any;
33
+ session:any;
34
+ term:any;
32
35
  user:any;
36
+ workspace:any;
33
37
  }
34
38
 
35
39
  export class Manifest extends Model {
@@ -39,7 +43,7 @@ export class Manifest extends Model {
39
43
  }
40
44
 
41
45
  public static makeManifestId(userId:ContentId):ContentId {
42
- return CachingHasher.makeMd5ContentId(userId + "-" + ContentKind.MANIFEST);
46
+ return CachingHasher.makeMd5Base62Hash(userId + "-" + ContentKind.MANIFEST) as ContentId;
43
47
  }
44
48
 
45
49
  public static create(userId:ContentId):Manifest {
@@ -57,8 +61,13 @@ export class Manifest extends Model {
57
61
  payload: {
58
62
  device : {},
59
63
  media : {},
64
+ metric : {},
60
65
  profile : {},
61
- user: {}
66
+ progress : {},
67
+ session : {},
68
+ term : {},
69
+ user: {},
70
+ workspace : {}
62
71
  }
63
72
  });
64
73
  }
@@ -1,8 +1,8 @@
1
1
  import { Doc } from '@shaxpir/sharedb/lib/client';
2
- import { ShareSync, ShareSyncFactory } from '../../repo/ShareSync';
3
- import { Content, ContentBody, ContentId, ContentMeta } from './Content';
2
+ import { MultiClock } from '@shaxpir/shaxpir-common';
3
+ import { ShareSync, ShareSyncFactory } from '../repo';
4
+ import { Content, ContentBody, ContentId, ContentMeta } from "./Content";
4
5
  import { ContentKind } from './ContentKind';
5
- import { MultiClock } from './Time';
6
6
 
7
7
  export interface MediaDimensions {
8
8
  width:number;
@@ -44,7 +44,6 @@ export class Media extends Content {
44
44
  return ShareSyncFactory.get().createContent({
45
45
  meta : {
46
46
  ref : mediaId,
47
- is_head : true,
48
47
  kind : ContentKind.MEDIA,
49
48
  id : mediaId,
50
49
  owner : userId,
@@ -0,0 +1,233 @@
1
+ import { Doc } from '@shaxpir/sharedb/lib/client';
2
+ import { CachingHasher, CompactDate, CompactDateTime, MultiClock, Time } from "@shaxpir/shaxpir-common";
3
+ import dayjs from 'dayjs';
4
+ import utc from 'dayjs/plugin/utc';
5
+ import { ShareSync, ShareSyncFactory } from '../repo';
6
+ import { Content, ContentBody, ContentId, ContentMeta } from "./Content";
7
+ import { ContentKind } from './ContentKind';
8
+ import { BatchOperation } from './Operation';
9
+
10
+ dayjs.extend(utc);
11
+
12
+ export enum MetricName {
13
+ WORD_COUNT = "word_count",
14
+ MINUTES_WRITING = "minutes_writing"
15
+ }
16
+
17
+ export interface MetricEntry {
18
+ date:CompactDate;
19
+ amount:number;
20
+ }
21
+
22
+ export interface MetricPayload {
23
+ metric_name:string;
24
+ min_date:CompactDate;
25
+ max_date:CompactDate;
26
+ entries:{[key:string]:number};
27
+ }
28
+
29
+ export interface MetricBody extends ContentBody {
30
+ meta:ContentMeta;
31
+ payload:MetricPayload;
32
+ }
33
+
34
+ export class Metric extends Content {
35
+
36
+ public static makeMetricId(userId:ContentId, metricName:MetricName):ContentId {
37
+ return CachingHasher.makeMd5Base62Hash(userId + "-metric-" + metricName) as ContentId;
38
+ }
39
+
40
+ public static create(
41
+ userId:ContentId,
42
+ metricName:MetricName,
43
+ entries:{[key:string]:number}
44
+ ):Metric {
45
+
46
+ const metricId = Metric.makeMetricId(userId, metricName);
47
+
48
+ // Find the min and max dates
49
+ let minDate:CompactDate = null as CompactDateTime;
50
+ let maxDate:CompactDate = null as CompactDateTime;
51
+ for (let d of Object.keys(entries)) {
52
+ const date:CompactDate = d as CompactDate;
53
+ if (minDate === null || Time.compareDate(date, minDate) < 0) {
54
+ minDate = date;
55
+ }
56
+ if (maxDate === null || Time.compareDate(date, maxDate) > 0) {
57
+ maxDate = date;
58
+ }
59
+ }
60
+ const now = MultiClock.now();
61
+ return ShareSyncFactory.get().createContent(
62
+ {
63
+ meta : {
64
+ ref : metricId,
65
+ kind : ContentKind.METRIC,
66
+ id : metricId,
67
+ owner : userId,
68
+ created_at : now,
69
+ updated_at : now
70
+ },
71
+ payload : {
72
+ metric_name : metricName,
73
+ min_date : minDate,
74
+ max_date : maxDate,
75
+ entries : entries
76
+ }
77
+ }
78
+ ) as Metric;
79
+ }
80
+
81
+ constructor(doc:Doc, shouldAcquire:boolean, shareSync:ShareSync) {
82
+ super(doc, shouldAcquire, shareSync);
83
+ }
84
+
85
+ public get payload():MetricPayload {
86
+ this.checkDisposed("Metric.payload");
87
+ return this.doc.data.payload as MetricPayload;
88
+ }
89
+
90
+ public get metricName():string {
91
+ this.checkDisposed("Metric.name");
92
+ return this.payload.metric_name;
93
+ }
94
+
95
+ public get minDate():CompactDate {
96
+ this.checkDisposed("Metric.minDate");
97
+ return this.payload.min_date;
98
+ }
99
+
100
+ public get maxDate():CompactDate {
101
+ this.checkDisposed("Metric.maxDate");
102
+ return this.payload.max_date;
103
+ }
104
+
105
+ public get length():number {
106
+ this.checkDisposed("Metric.length");
107
+ const minMoment:any = dayjs.utc(this.minDate, Time.DATE_FORMAT);
108
+ const maxMoment:any = dayjs.utc(this.maxDate, Time.DATE_FORMAT);
109
+ return Math.abs(maxMoment.diff(minMoment, "days")) + 1;
110
+ }
111
+
112
+ public get(index:number):MetricEntry {
113
+ this.checkDisposed("Metric.get");
114
+ if (index === 0) {
115
+ return {
116
+ date: this.minDate,
117
+ amount: this.forDate(this.minDate)
118
+ };
119
+ } else {
120
+ const minMoment:any = dayjs.utc(this.minDate, Time.DATE_FORMAT);
121
+ const offsetDate:CompactDate = minMoment.add(index, 'days').format(Time.DATE_FORMAT) as CompactDate;
122
+ return {
123
+ date: offsetDate,
124
+ amount: this.forDate(offsetDate)
125
+ };
126
+ }
127
+ }
128
+
129
+ public sumBetween(minDate:CompactDate, maxDate:CompactDate):number {
130
+ this.checkDisposed("Metric.sumBetween");
131
+ let sum:number = 0;
132
+ const dates:CompactDate[] = Time.datesBetween(minDate, maxDate);
133
+ for (let i = 0, len = dates.length; i < len; i++) {
134
+ const date:CompactDate = dates[i];
135
+ sum += this.forDate(date);
136
+ }
137
+ return sum;
138
+ }
139
+
140
+ public forDate(date:CompactDate):number {
141
+ this.checkDisposed("Metric.forDate");
142
+ const map:any = this.payload.entries;
143
+ if (map.hasOwnProperty(date)) {
144
+ return map[date as string];
145
+ }
146
+ return 0.0;
147
+ }
148
+
149
+ public nonZeroDayCount():number {
150
+ this.checkDisposed("Metric.nonZeroDayCount");
151
+ let count:number = 0;
152
+ const map:any = this.payload.entries;
153
+ for (let date of Object.keys(map)) {
154
+ if (map[date] !== 0.0) {
155
+ count++;
156
+ }
157
+ }
158
+ return count;
159
+ }
160
+
161
+ public setDateAmount(date:CompactDate, amount:number):void {
162
+ this.checkDisposed("Metric.setDateAmount");
163
+
164
+ const prevMinDate = this.payload.min_date;
165
+ const prevMaxDate = this.payload.max_date;
166
+
167
+ const batch = new BatchOperation(this);
168
+ batch.setPathValue([ 'payload', 'entries', date ] , amount);
169
+
170
+ if (prevMinDate === null || Time.compareDate(date, prevMinDate) < 0) {
171
+ batch.setPathValue([ 'payload', 'min_date' ] , date);
172
+ }
173
+ if (prevMaxDate === null || Time.compareDate(date, prevMaxDate) > 0) {
174
+ batch.setPathValue([ 'payload', 'max_date' ] , date);
175
+ }
176
+
177
+ batch.commit();
178
+ }
179
+
180
+ public incrementDateAmounts(dateAmounts:{[key:string]:number}):void {
181
+ this.checkDisposed("Metric.incrementDateAmounts");
182
+
183
+ const prevMinDate = this.payload.min_date;
184
+ const prevMaxDate = this.payload.max_date;
185
+
186
+ let minDate = prevMinDate;
187
+ let maxDate = prevMaxDate;
188
+
189
+ const batch = new BatchOperation(this);
190
+
191
+ const dates = Object.keys(dateAmounts);
192
+ for (let i = 0; i < dates.length; i++) {
193
+ const date:CompactDate = dates[i] as CompactDate;
194
+
195
+ const prevAmount:number = this.forDate(date);
196
+ const newAmount:number = dateAmounts[date];
197
+
198
+ batch.setPathValue([ 'payload', 'entries', date ] , prevAmount + newAmount);
199
+
200
+ if (minDate === null || Time.compareDate(date, minDate) < 0) {
201
+ minDate = date;
202
+ }
203
+ if (maxDate === null || Time.compareDate(date, maxDate) > 0) {
204
+ maxDate = date;
205
+ }
206
+ }
207
+
208
+ if (minDate != prevMinDate) {
209
+ batch.setPathValue([ 'payload', 'min_date' ] , minDate);
210
+ }
211
+ if (maxDate != prevMaxDate) {
212
+ batch.setPathValue([ 'payload', 'max_date' ] , maxDate);
213
+ }
214
+
215
+ batch.commit();
216
+ }
217
+
218
+ public static forEachEntry(
219
+ body:MetricBody,
220
+ callback:(entry:MetricEntry) => void
221
+ ):void {
222
+ const dates = Object.keys(body.payload.entries);
223
+ for (let i = 0; i < dates.length; i++) {
224
+ const date = dates[i] as CompactDate;
225
+ const amount = body.payload.entries[date] as number;
226
+ callback({
227
+ date : date,
228
+ amount : amount
229
+ });
230
+ }
231
+ }
232
+
233
+ }
@@ -1,13 +1,11 @@
1
1
  import { Doc } from '@shaxpir/sharedb/lib/client';
2
- import { ShareSync } from '../../repo/ShareSync';
3
- import { Struct } from '../../util/Struct';
4
- import { Dispatch, DispatchTopic } from '../../util/Dispatch';
5
- import { ChangeModel } from '../markup/ChangeModel';
6
- import { ContentId, ContentMeta, ContentRef } from './Content';
2
+ import { CompactDateTime, Dispatch, DispatchTopic, Struct } from '@shaxpir/shaxpir-common';
3
+ import { ShareSync } from '../repo';
4
+ import { ContentId, ContentMeta, ContentRef } from "./Content";
7
5
  import { ContentKind } from './ContentKind';
8
6
  import { ManifestBody } from './Manifest';
9
7
  import { PermissionType } from './Permissions';
10
- import { CompactDateTime } from './Time';
8
+ import { ChangeModel } from './ChangeModel';
11
9
 
12
10
  export abstract class Model {
13
11
 
@@ -1,15 +1,12 @@
1
- import { Op as DeltaOp } from "@shaxpir/quill-delta";
2
1
  import { Doc } from '@shaxpir/sharedb/lib/client';
3
- import { ShareSyncFactory } from '../../repo/ShareSync';
4
- import { Struct } from '../../util/Struct';
5
- import { Content } from '../content/Content';
6
- import { Model } from '../content/Model';
7
- import { MultiClock, MultiTime } from '../content/Time';
8
- import { TextEditOps } from './TextEditOps';
2
+ import { MultiClock, MultiTime, Struct } from '@shaxpir/shaxpir-common';
3
+ import { TextEditOps } from '../repo/TextEditOps';
9
4
 
10
- import * as Json1 from '../../repo/PermissiveJson1';
5
+ import * as Json1 from '../repo/PermissiveJson1';
6
+ import { Model } from './Model';
7
+ import { ShareSyncFactory } from '../repo';
8
+ import { Content } from './Content';
11
9
 
12
- const RichText = require('@shaxpir/rich-text');
13
10
  const UnicodeText = require('ot-text-unicode');
14
11
 
15
12
  export type JsonPathElement = string | number;
@@ -184,13 +181,6 @@ export class BatchOperation {
184
181
  }
185
182
  }
186
183
 
187
- public applyRichText(
188
- path:JsonPath,
189
- deltaOps:DeltaOp[]
190
- ):void {
191
- this.ops.push(Json1.editOp(path, RichText.type, deltaOps));
192
- }
193
-
194
184
  public commit():void {
195
185
  const batch = this;
196
186
  if (batch.ops.length > 0) {
@@ -1,5 +1,3 @@
1
- import { ContentId } from "./Content";
2
-
3
1
  export enum PermissionType {
4
2
  READ,
5
3
  WRITE
@@ -0,0 +1,53 @@
1
+ import { CompactDateTime } from "@shaxpir/shaxpir-common";
2
+ import { ContentId } from "./Content";
3
+ import { ReviewLike } from "./Review";
4
+
5
+ export interface PhraseExample {
6
+ id: number;
7
+ text: string;
8
+ pinyin: string;
9
+ translation: string;
10
+ learn_rank: number;
11
+ sense_rank: number;
12
+ }
13
+
14
+ export interface Phrase {
15
+ text: string;
16
+ hanzi_count: number;
17
+ sense_rank: number;
18
+ learn_rank: number;
19
+ pinyin: string;
20
+ pinyin_tokenized: string;
21
+ transliteration: string;
22
+ translation: string;
23
+ notes: string;
24
+ examples?: PhraseExample[];
25
+ components?: PhraseExample[];
26
+ keywords?: string[];
27
+ tags?: string[];
28
+ }
29
+
30
+ export interface BuiltInPhrase extends Phrase {
31
+ id: number;
32
+ }
33
+
34
+ export interface AnnotatedPhrase extends Phrase {
35
+
36
+ // Always populated. If this is a builtin entry, it will be `phrase-${phrase_id}`.
37
+ // If this is a user-specific entry, it will be `term-${term_id}`.
38
+ id: string;
39
+
40
+ // if this is populated, the Phrase comes from the built-in database
41
+ phrase_id?: number;
42
+
43
+ // if this is populated, then there is a user-specific Term model associated with this Phrase
44
+ content_id?: ContentId;
45
+
46
+ // All these fields come from the Term model, if it exists. If it doesn't exist, then these fields
47
+ // have default values (null for starred_at, numbers are zero, arrays are empty, etc.)
48
+ starred_at: CompactDateTime | null;
49
+ alpha: number;
50
+ beta: number;
51
+ proficiency: number;
52
+ reviews: ReviewLike[];
53
+ }
@@ -1,11 +1,10 @@
1
1
  import { Doc } from '@shaxpir/sharedb/lib/client';
2
- import { ShareSync, ShareSyncFactory } from '../../repo/ShareSync';
3
- import { CachingHasher } from '../../util/CachingHasher';
4
- import { BatchOperation } from '../markup/Operation';
2
+ import { CachingHasher, MultiClock } from '@shaxpir/shaxpir-common';
3
+ import { ShareSync, ShareSyncFactory } from '../repo';
5
4
  import { Content, ContentBody, ContentId, ContentMeta, ContentRef } from "./Content";
6
5
  import { ContentKind } from './ContentKind';
7
6
  import { MediaCropping } from './Media';
8
- import { MultiClock } from './Time';
7
+ import { BatchOperation } from './Operation';
9
8
 
10
9
  export interface ProfilePayload {
11
10
  username:string;
@@ -22,7 +21,7 @@ export interface ProfileBody extends ContentBody {
22
21
  export class Profile extends Content {
23
22
 
24
23
  public static makeProfileId(userId:ContentId):ContentId {
25
- return CachingHasher.makeMd5ContentId(userId + "-" + ContentKind.PROFILE);
24
+ return CachingHasher.makeMd5Base62Hash(userId + "-" + ContentKind.PROFILE) as ContentId;
26
25
  }
27
26
 
28
27
  public static create(userId:ContentId):Profile {
@@ -32,7 +31,6 @@ export class Profile extends Content {
32
31
  {
33
32
  meta : {
34
33
  ref : profileId,
35
- is_head : true,
36
34
  kind : ContentKind.PROFILE,
37
35
  id : profileId,
38
36
  owner : userId,