@shaxpir/duiduidui-models 1.0.0 → 1.1.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.
- package/dist/models/{content/ArrayView.d.ts → ArrayView.d.ts} +1 -1
- package/dist/models/{content/ArrayView.js → ArrayView.js} +14 -14
- package/dist/models/BayesianScore.d.ts +9 -0
- package/dist/models/BayesianScore.js +27 -0
- package/dist/models/{markup/ChangeModel.d.ts → ChangeModel.d.ts} +2 -3
- package/dist/models/{markup/ChangeModel.js → ChangeModel.js} +20 -10
- package/dist/models/{content/Content.d.ts → Content.d.ts} +9 -10
- package/dist/models/{content/Content.js → Content.js} +2 -6
- package/dist/models/{content/ContentKind.d.ts → ContentKind.d.ts} +3 -0
- package/dist/models/{content/ContentKind.js → ContentKind.js} +5 -1
- package/dist/models/{content/Device.d.ts → Device.d.ts} +15 -7
- package/dist/models/{content/Device.js → Device.js} +14 -18
- package/dist/models/Hanzi.d.ts +15 -0
- package/dist/models/{content/Manifest.d.ts → Manifest.d.ts} +7 -3
- package/dist/models/{content/Manifest.js → Manifest.js} +12 -8
- package/dist/models/{content/Media.d.ts → Media.d.ts} +2 -3
- package/dist/models/{content/Media.js → Media.js} +4 -5
- package/dist/models/{content/Metric.d.ts → Metric.d.ts} +2 -3
- package/dist/models/{content/Metric.js → Metric.js} +18 -20
- package/dist/models/{content/Model.d.ts → Model.d.ts} +3 -5
- package/dist/models/{content/Model.js → Model.js} +5 -6
- package/dist/models/{markup/Operation.d.ts → Operation.d.ts} +2 -5
- package/dist/models/{markup/Operation.js → Operation.js} +30 -25
- package/dist/models/Phrase.d.ts +39 -0
- package/dist/models/{content/Profile.d.ts → Profile.d.ts} +1 -2
- package/dist/models/{content/Profile.js → Profile.js} +7 -9
- package/dist/models/Progress.d.ts +26 -0
- package/dist/models/Progress.js +39 -0
- package/dist/models/Review.d.ts +14 -0
- package/dist/models/{content/Session.d.ts → Session.d.ts} +7 -15
- package/dist/models/Session.js +103 -0
- package/dist/models/Term.d.ts +36 -0
- package/dist/models/Term.js +82 -0
- package/dist/models/User.d.ts +32 -0
- package/dist/models/User.js +65 -0
- package/dist/models/Workspace.d.ts +37 -0
- package/dist/models/Workspace.js +94 -0
- package/dist/models/index.d.ts +22 -4
- package/dist/models/index.js +22 -4
- package/dist/repo/PermissiveJson1.d.ts +16 -16
- package/dist/repo/PermissiveJson1.js +17 -7
- package/dist/repo/ShareSync.d.ts +6 -6
- package/dist/repo/ShareSync.js +26 -19
- package/dist/repo/index.d.ts +1 -0
- package/dist/repo/index.js +1 -0
- package/dist/util/index.d.ts +0 -14
- package/dist/util/index.js +0 -14
- package/lib/index.ts +5 -0
- package/lib/models/{content/ArrayView.ts → ArrayView.ts} +2 -2
- package/lib/models/BayesianScore.ts +32 -0
- package/lib/models/{markup/ChangeModel.ts → ChangeModel.ts} +3 -4
- package/lib/models/{content/Content.ts → Content.ts} +15 -18
- package/lib/models/{content/ContentKind.ts → ContentKind.ts} +6 -1
- package/lib/models/{content/Device.ts → Device.ts} +26 -22
- package/lib/models/Hanzi.ts +16 -0
- package/lib/models/{content/Manifest.ts → Manifest.ts} +15 -6
- package/lib/models/{content/Media.ts → Media.ts} +3 -4
- package/lib/models/Metric.ts +233 -0
- package/lib/models/{content/Model.ts → Model.ts} +4 -6
- package/lib/models/{markup/Operation.ts → Operation.ts} +6 -16
- package/lib/models/{content/Permissions.ts → Permissions.ts} +0 -2
- package/lib/models/Phrase.ts +53 -0
- package/lib/models/{content/Profile.ts → Profile.ts} +4 -6
- package/lib/models/Progress.ts +66 -0
- package/lib/models/Review.ts +18 -0
- package/lib/models/Session.ts +140 -0
- package/lib/models/Term.ts +139 -0
- package/lib/models/User.ts +97 -0
- package/lib/models/Workspace.ts +129 -0
- package/lib/models/index.ts +24 -0
- package/lib/repo/ShareSync.ts +9 -13
- package/lib/repo/index.ts +6 -0
- package/lib/util/index.ts +4 -0
- package/package.json +4 -15
- package/dist/models/OutboundMessage.d.ts +0 -18
- package/dist/models/OutboundMessage.js +0 -25
- package/dist/models/content/Activity.d.ts +0 -10
- package/dist/models/content/Billing.d.ts +0 -144
- package/dist/models/content/Billing.js +0 -418
- package/dist/models/content/Book.d.ts +0 -77
- package/dist/models/content/Book.js +0 -407
- package/dist/models/content/Category.d.ts +0 -16
- package/dist/models/content/Category.js +0 -20
- package/dist/models/content/Checkpointable.d.ts +0 -21
- package/dist/models/content/Checkpointable.js +0 -156
- package/dist/models/content/Comment.d.ts +0 -19
- package/dist/models/content/Comment.js +0 -53
- package/dist/models/content/ConceptArt.d.ts +0 -31
- package/dist/models/content/ConceptArt.js +0 -84
- package/dist/models/content/Context.d.ts +0 -28
- package/dist/models/content/Context.js +0 -162
- package/dist/models/content/DevEnv.d.ts +0 -5
- package/dist/models/content/DevEnv.js +0 -9
- package/dist/models/content/Dictionary.d.ts +0 -31
- package/dist/models/content/Dictionary.js +0 -5
- package/dist/models/content/DictionaryEntry.d.ts +0 -20
- package/dist/models/content/DictionaryEntry.js +0 -2
- package/dist/models/content/ElasticModel.d.ts +0 -149
- package/dist/models/content/ElasticModel.js +0 -179
- package/dist/models/content/Environment.d.ts +0 -61
- package/dist/models/content/Environment.js +0 -124
- package/dist/models/content/ExportOptions.d.ts +0 -64
- package/dist/models/content/ExportOptions.js +0 -213
- package/dist/models/content/Folder.d.ts +0 -16
- package/dist/models/content/Folder.js +0 -33
- package/dist/models/content/Fragment.d.ts +0 -54
- package/dist/models/content/Fragment.js +0 -181
- package/dist/models/content/Hanzi.d.ts +0 -21
- package/dist/models/content/HighlightRule.d.ts +0 -9
- package/dist/models/content/HighlightRule.js +0 -2
- package/dist/models/content/Migration.d.ts +0 -68
- package/dist/models/content/Migration.js +0 -155
- package/dist/models/content/Phrase.d.ts +0 -8
- package/dist/models/content/Placeholder.d.ts +0 -8
- package/dist/models/content/Placeholder.js +0 -36
- package/dist/models/content/RichText.d.ts +0 -58
- package/dist/models/content/RichText.js +0 -79
- package/dist/models/content/Session.js +0 -173
- package/dist/models/content/Speech.d.ts +0 -67
- package/dist/models/content/Speech.js +0 -97
- package/dist/models/content/Stub.d.ts +0 -24
- package/dist/models/content/Stub.js +0 -179
- package/dist/models/content/Time.d.ts +0 -56
- package/dist/models/content/Time.js +0 -295
- package/dist/models/content/User.d.ts +0 -36
- package/dist/models/content/User.js +0 -95
- package/dist/models/content/Workspace.d.ts +0 -71
- package/dist/models/content/Workspace.js +0 -237
- package/dist/models/content/index.d.ts +0 -36
- package/dist/models/content/index.js +0 -53
- package/dist/models/legacy/LegacyBodyFormat.d.ts +0 -9
- package/dist/models/legacy/LegacyBodyFormat.js +0 -2
- package/dist/models/legacy/LegacyComment.d.ts +0 -12
- package/dist/models/legacy/LegacyComment.js +0 -2
- package/dist/models/legacy/LegacyContent.d.ts +0 -53
- package/dist/models/legacy/LegacyContent.js +0 -55
- package/dist/models/legacy/LegacyConversion.d.ts +0 -55
- package/dist/models/legacy/LegacyConversion.js +0 -401
- package/dist/models/legacy/LegacyFragment.d.ts +0 -21
- package/dist/models/legacy/LegacyFragment.js +0 -2
- package/dist/models/legacy/LegacyLocator.d.ts +0 -8
- package/dist/models/legacy/LegacyLocator.js +0 -31
- package/dist/models/legacy/LegacyOutboundMessage.d.ts +0 -16
- package/dist/models/legacy/LegacyOutboundMessage.js +0 -13
- package/dist/models/legacy/LegacyPicture.d.ts +0 -14
- package/dist/models/legacy/LegacyPicture.js +0 -2
- package/dist/models/legacy/LegacyProfile.d.ts +0 -9
- package/dist/models/legacy/LegacyProfile.js +0 -2
- package/dist/models/legacy/LegacySession.d.ts +0 -41
- package/dist/models/legacy/LegacySession.js +0 -35
- package/dist/models/legacy/LegacyStory.d.ts +0 -23
- package/dist/models/legacy/LegacyStory.js +0 -2
- package/dist/models/legacy/LegacyStub.d.ts +0 -15
- package/dist/models/legacy/LegacyStub.js +0 -2
- package/dist/models/legacy/LegacyTransaction.d.ts +0 -14
- package/dist/models/legacy/LegacyTransaction.js +0 -49
- package/dist/models/legacy/LegacyUser.d.ts +0 -28
- package/dist/models/legacy/LegacyUser.js +0 -32
- package/dist/models/legacy/LegacyWorkspace.d.ts +0 -23
- package/dist/models/legacy/LegacyWorkspace.js +0 -6
- package/dist/models/legacy/index.d.ts +0 -15
- package/dist/models/legacy/index.js +0 -32
- package/dist/models/markup/BodyFormat.d.ts +0 -14
- package/dist/models/markup/BodyFormat.js +0 -190
- package/dist/models/markup/DeltaOps.d.ts +0 -5
- package/dist/models/markup/DeltaOps.js +0 -74
- package/dist/models/markup/HtmlMarkup.d.ts +0 -4
- package/dist/models/markup/HtmlMarkup.js +0 -21
- package/dist/models/markup/index.d.ts +0 -6
- package/dist/models/markup/index.js +0 -23
- package/dist/util/Async.d.ts +0 -8
- package/dist/util/Async.js +0 -18
- package/dist/util/Base62.d.ts +0 -6
- package/dist/util/Base62.js +0 -47
- package/dist/util/BinarySearch.d.ts +0 -7
- package/dist/util/BinarySearch.js +0 -46
- package/dist/util/CachingHasher.d.ts +0 -8
- package/dist/util/CachingHasher.js +0 -41
- package/dist/util/Color.d.ts +0 -32
- package/dist/util/Color.js +0 -204
- package/dist/util/Dispatch.d.ts +0 -15
- package/dist/util/Dispatch.js +0 -79
- package/dist/util/EditDistance.d.ts +0 -13
- package/dist/util/EditDistance.js +0 -184
- package/dist/util/NumberFormat.d.ts +0 -14
- package/dist/util/NumberFormat.js +0 -224
- package/dist/util/Struct.d.ts +0 -4
- package/dist/util/Struct.js +0 -15
- package/dist/util/Template.d.ts +0 -16
- package/dist/util/Template.js +0 -128
- package/dist/util/Text.d.ts +0 -45
- package/dist/util/Text.js +0 -243
- package/dist/util/Tuples.d.ts +0 -9
- package/dist/util/Tuples.js +0 -135
- package/dist/util/Validate.d.ts +0 -4
- package/dist/util/Validate.js +0 -11
- package/dist/util/Vocabulary.d.ts +0 -3
- package/dist/util/Vocabulary.js +0 -35
- package/lib/models/content/Billing.ts +0 -558
- package/lib/models/content/DevEnv.ts +0 -5
- package/lib/models/content/DictionaryEntry.ts +0 -22
- package/lib/models/content/Hanzi.ts +0 -25
- package/lib/models/content/Phrase.ts +0 -10
- package/lib/models/content/Time.ts +0 -328
- package/lib/models/content/User.ts +0 -130
- package/lib/models/markup/DeltaOps.ts +0 -71
- package/lib/util/Base62.ts +0 -47
- package/lib/util/CachingHasher.ts +0 -38
- package/lib/util/Dispatch.ts +0 -92
- package/lib/util/NumberFormat.ts +0 -194
- package/lib/util/Struct.ts +0 -14
- package/lib/util/Tuples.ts +0 -131
- /package/dist/models/{content/GeoLocation.d.ts → GeoLocation.d.ts} +0 -0
- /package/dist/models/{content/GeoLocation.js → GeoLocation.js} +0 -0
- /package/dist/models/{content/Hanzi.js → Hanzi.js} +0 -0
- /package/dist/models/{content/Permissions.d.ts → Permissions.d.ts} +0 -0
- /package/dist/models/{content/Permissions.js → Permissions.js} +0 -0
- /package/dist/models/{content/Phrase.js → Phrase.js} +0 -0
- /package/dist/models/{content/Activity.js → Review.js} +0 -0
- /package/dist/{models/markup → repo}/TextEditOps.d.ts +0 -0
- /package/dist/{models/markup → repo}/TextEditOps.js +0 -0
- /package/lib/models/{content/GeoLocation.ts → GeoLocation.ts} +0 -0
- /package/lib/{models/markup → repo}/TextEditOps.ts +0 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
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 {
|
|
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:
|
|
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 {
|
|
3
|
-
import {
|
|
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 {
|
|
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 {
|
|
10
|
+
import { ProgressPayload } from './Progress';
|
|
11
|
+
import { SessionPayload } from './Session';
|
|
12
|
+
import { TermPayload } from './Term';
|
|
12
13
|
import { UserPayload } from './User';
|
|
13
|
-
import {
|
|
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
|
-
|
|
44
|
-
| HanziPayload
|
|
45
|
-
| PhrasePayload
|
|
46
|
-
| DevicePayload
|
|
43
|
+
DevicePayload
|
|
47
44
|
| MediaPayload
|
|
45
|
+
| MetricPayload
|
|
48
46
|
| ProfilePayload
|
|
49
|
-
|
|
|
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
|
-
//
|
|
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 {
|
|
3
|
-
import {
|
|
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 {
|
|
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.
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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', '
|
|
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 {
|
|
3
|
-
import {
|
|
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 {
|
|
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.
|
|
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
|
-
|
|
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 {
|
|
3
|
-
import {
|
|
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 {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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 {
|
|
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 {
|
|
4
|
-
import {
|
|
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 '
|
|
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) {
|
|
@@ -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 {
|
|
3
|
-
import {
|
|
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 {
|
|
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.
|
|
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,
|