@kokimoki/app 0.0.3 → 0.0.6

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/fields.d.ts CHANGED
@@ -53,6 +53,7 @@ export declare class FormArray<T> extends Field<T[]> {
53
53
  get schema(): {
54
54
  type: string;
55
55
  items: any;
56
+ default: T;
56
57
  };
57
58
  }
58
59
  export declare class TaskField extends Field<Task> {
package/dist/fields.js CHANGED
@@ -81,6 +81,7 @@ export class FormArray extends Field {
81
81
  return {
82
82
  type: "array",
83
83
  items: field.schema,
84
+ default: field.value,
84
85
  };
85
86
  }
86
87
  }
@@ -1,8 +1,8 @@
1
1
  import { HocuspocusProvider } from "@hocuspocus/provider";
2
2
  import type TypedEmitter from "typed-emitter";
3
- import { SyncedStore } from "./synced-store";
3
+ import type { SyncedStore } from "./synced-store";
4
4
  import type { DocTypeDescription } from "@syncedstore/core/types/doc";
5
- import { UploadedMedia } from "./types/api";
5
+ import type { UploadedMedia } from "./types/api";
6
6
  export type KokimokiClientEvents<T> = {
7
7
  stateless: (room: string, from: string, data: T) => void;
8
8
  };
@@ -21,7 +21,7 @@ export declare class KokimokiClient<StatelessDataT = any> extends KokimokiClient
21
21
  connect(): Promise<void>;
22
22
  setProvider<T extends DocTypeDescription>(name: string, store: SyncedStore<T>): Promise<void>;
23
23
  removeProvider(name: string): void;
24
- getProvider(name: string): HocuspocusProvider;
24
+ getProvider(name: string): HocuspocusProvider | undefined;
25
25
  serverTimestamp(): number;
26
26
  sendStatelessToClient(room: string, clientId: string, data: StatelessDataT): void;
27
27
  sendStatelessToRoom(room: string, data: StatelessDataT, self?: boolean): void;
@@ -1,4 +1,4 @@
1
- import * as Y from "yjs";
1
+ import type * as Y from "yjs";
2
2
  import type { DocTypeDescription, MappedTypeDescription } from "@syncedstore/core/types/doc";
3
3
  export declare class SyncedStore<T extends DocTypeDescription> {
4
4
  readonly data: MappedTypeDescription<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kokimoki/app",
3
- "version": "0.0.3",
3
+ "version": "0.0.6",
4
4
  "type": "module",
5
5
  "description": "Kokimoki app",
6
6
  "main": "dist/index.js",
@@ -16,6 +16,7 @@
16
16
  "author": "Loquiz OÜ",
17
17
  "license": "Apache-2.0",
18
18
  "devDependencies": {
19
+ "@types/ws": "^8.5.5",
19
20
  "typescript": "^5.1.6"
20
21
  },
21
22
  "dependencies": {
@@ -1,30 +0,0 @@
1
- import { HocuspocusProvider } from "@hocuspocus/provider";
2
- import type TypedEmitter from "typed-emitter";
3
- import { SyncedStore } from "./synced-store";
4
- import type { DocTypeDescription } from "@syncedstore/core/types/doc";
5
- import { UploadedMedia } from "./types";
6
- export type KokimokiClientEvents<T> = {
7
- stateless: (room: string, from: string, data: T) => void;
8
- };
9
- declare const KokimokiClient_base: new <T>() => TypedEmitter<KokimokiClientEvents<T>>;
10
- export declare class KokimokiClient<StatelessDataT = any> extends KokimokiClient_base<StatelessDataT> {
11
- readonly appId: string;
12
- serverTimeOffset: number;
13
- wsUrl: string;
14
- apiUrl: string;
15
- private _id;
16
- private _token;
17
- private _providers;
18
- constructor(host: string, appId: string);
19
- get id(): string;
20
- get token(): string;
21
- connect(): Promise<void>;
22
- setProvider<T extends DocTypeDescription>(name: string, store: SyncedStore<T>): Promise<void>;
23
- removeProvider(name: string): void;
24
- getProvider(name: string): HocuspocusProvider;
25
- serverTimestamp(): number;
26
- sendStatelessToClient(room: string, clientId: string, data: StatelessDataT): void;
27
- sendStatelessToRoom(room: string, data: StatelessDataT, self?: boolean): void;
28
- mediaUpload(blob: Blob): Promise<UploadedMedia>;
29
- }
30
- export {};
@@ -1,116 +0,0 @@
1
- import { HocuspocusProvider } from "@hocuspocus/provider";
2
- import EventEmitter from "events";
3
- import { sendMediaUpload } from "./api/sendMediaUpload";
4
- import { getETags } from "./api/getETags";
5
- import { uploadMedia } from "./api/uploadMedia";
6
- import { errorMessage } from "./utils";
7
- import { fetchAuth } from "./api/fetchAuth";
8
- export class KokimokiClient extends EventEmitter {
9
- appId;
10
- serverTimeOffset = 0;
11
- wsUrl;
12
- apiUrl;
13
- _id = "";
14
- _token = "";
15
- _providers = new Map();
16
- constructor(host, appId) {
17
- super();
18
- this.appId = appId;
19
- const secure = !host.match(/^localhost/);
20
- this.wsUrl = `ws${secure ? "s" : ""}://${host}`;
21
- this.apiUrl = `http${secure ? "s" : ""}://${host}`;
22
- }
23
- get id() {
24
- if (!this._id) {
25
- throw new Error("Client not connected");
26
- }
27
- return this._id;
28
- }
29
- get token() {
30
- if (!this._token) {
31
- throw new Error("Client not connected");
32
- }
33
- return this._token;
34
- }
35
- async connect() {
36
- let clientToken = localStorage.getItem("KM_TOKEN");
37
- const startTime = Date.now();
38
- const { clientId, appToken, serverTime, token } = await fetchAuth({
39
- appId: this.appId,
40
- clientToken,
41
- apiUrl: this.apiUrl,
42
- });
43
- const endTime = Date.now();
44
- const ping = Math.round((endTime - startTime) / 2);
45
- this._id = clientId;
46
- this._token = appToken;
47
- this.serverTimeOffset = Date.now() - serverTime - ping;
48
- localStorage.setItem("KM_TOKEN", token);
49
- console.log("READY", token);
50
- }
51
- async setProvider(name, store) {
52
- const provider = new HocuspocusProvider({
53
- url: `${this.wsUrl}/connection`,
54
- name: `${this.appId}/${name}`,
55
- document: store.doc,
56
- token: this.token,
57
- });
58
- this._providers.set(name, provider);
59
- // Handle incoming stateless messages
60
- provider.on("stateless", (e) => {
61
- const payload = JSON.parse(e.payload);
62
- this.emit("stateless", name, payload.from, payload.data);
63
- });
64
- // Wait for initial sync
65
- await new Promise((resolve) => {
66
- const handler = () => {
67
- provider.off("synced", handler);
68
- resolve();
69
- };
70
- provider.on("synced", handler);
71
- });
72
- }
73
- removeProvider(name) {
74
- const provider = this._providers.get(name);
75
- if (!provider) {
76
- throw new Error(`No provider for room ${name}`);
77
- }
78
- provider.destroy();
79
- this._providers.delete(name);
80
- }
81
- getProvider(name) {
82
- return this._providers.get(name);
83
- }
84
- serverTimestamp() {
85
- return Date.now() - this.serverTimeOffset;
86
- }
87
- sendStatelessToClient(room, clientId, data) {
88
- const provider = this._providers.get(room);
89
- if (!provider) {
90
- throw new Error(`No provider for room ${room}`);
91
- }
92
- provider.sendStateless(JSON.stringify({ to: clientId, data }));
93
- }
94
- sendStatelessToRoom(room, data, self = false) {
95
- const provider = this._providers.get(room);
96
- if (!provider) {
97
- throw new Error(`No provider for room ${room}`);
98
- }
99
- provider.sendStateless(JSON.stringify({ data, self }));
100
- }
101
- async mediaUpload(blob) {
102
- try {
103
- const uploadData = await sendMediaUpload(blob, {
104
- apiUrl: this.apiUrl,
105
- appToken: this.token,
106
- });
107
- const { id } = uploadData;
108
- const etags = await getETags(blob, uploadData);
109
- const { url } = await uploadMedia({ id, etags }, { apiUrl: this.apiUrl, appToken: this.token });
110
- return { url, id };
111
- }
112
- catch (error) {
113
- throw new Error(`Error while uploading media: ${errorMessage(error)}`);
114
- }
115
- }
116
- }
@@ -1,29 +0,0 @@
1
- import { HocuspocusProvider } from "@hocuspocus/provider";
2
- import type { Y } from "@syncedstore/core";
3
- import type TypedEmitter from "typed-emitter";
4
- import type { UploadedMedia } from "./types";
5
- type KokimokiClientEvents<T> = {
6
- stateless: (room: string, from: string, data: T) => void;
7
- };
8
- declare const KokimokiClient_base: new <T>() => TypedEmitter<KokimokiClientEvents<T>>;
9
- export declare class KokimokiClient<StatelessDataT = any> extends KokimokiClient_base<StatelessDataT> {
10
- readonly appId: string;
11
- serverTimeOffset: number;
12
- wsUrl: string;
13
- apiUrl: string;
14
- private _id;
15
- private _token;
16
- private _providers;
17
- constructor(host: string, appId: string);
18
- get id(): string;
19
- get token(): string;
20
- connect(): Promise<void>;
21
- setProvider(name: string, document: Y.Doc): Promise<void>;
22
- removeProvider(name: string): void;
23
- getProvider(name: string): HocuspocusProvider;
24
- serverTimestamp(): number;
25
- sendStatelessToClient(room: string, clientId: string, data: StatelessDataT): void;
26
- sendStatelessToRoom(room: string, data: StatelessDataT, self?: boolean): void;
27
- mediaUpload(blob: Blob): Promise<UploadedMedia>;
28
- }
29
- export {};
@@ -1,116 +0,0 @@
1
- import { HocuspocusProvider } from "@hocuspocus/provider";
2
- import EventEmitter from "events";
3
- import { errorMessage } from "./utils";
4
- import { fetchAuth } from "./api/fetchAuth";
5
- import { sendMediaUpload } from "./api/sendMediaUpload";
6
- import { getETags } from "./api/getETags";
7
- import { uploadMedia } from "./api/uploadMedia";
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
- export class KokimokiClient extends EventEmitter {
10
- appId;
11
- serverTimeOffset = 0;
12
- wsUrl;
13
- apiUrl;
14
- _id = "";
15
- _token = "";
16
- _providers = new Map();
17
- constructor(host, appId) {
18
- super();
19
- this.appId = appId;
20
- const secure = !host.match(/^localhost/);
21
- this.wsUrl = `ws${secure ? "s" : ""}://${host}`;
22
- this.apiUrl = `http${secure ? "s" : ""}://${host}`;
23
- }
24
- get id() {
25
- if (!this._id) {
26
- throw new Error("Client not connected");
27
- }
28
- return this._id;
29
- }
30
- get token() {
31
- if (!this._token) {
32
- throw new Error("Client not connected");
33
- }
34
- return this._token;
35
- }
36
- async connect() {
37
- const clientToken = localStorage.getItem("KM_TOKEN");
38
- const startTime = Date.now();
39
- const { clientId, appToken, serverTime, token } = await fetchAuth({
40
- appId: this.appId,
41
- clientToken,
42
- apiUrl: this.apiUrl,
43
- });
44
- const endTime = Date.now();
45
- const ping = Math.round((endTime - startTime) / 2);
46
- this._id = clientId;
47
- this._token = appToken;
48
- this.serverTimeOffset = Date.now() - serverTime - ping;
49
- localStorage.setItem("KM_TOKEN", token);
50
- }
51
- async setProvider(name, document) {
52
- const provider = new HocuspocusProvider({
53
- url: `${this.wsUrl}/connection`,
54
- name: `${this.appId}/${name}`,
55
- document,
56
- token: this.token,
57
- });
58
- this._providers.set(name, provider);
59
- // Handle incoming stateless messages
60
- provider.on("stateless", (e) => {
61
- const payload = JSON.parse(e.payload);
62
- this.emit("stateless", name, payload.from, payload.data);
63
- });
64
- // Wait for initial sync
65
- await new Promise((resolve) => {
66
- const handler = () => {
67
- provider.off("synced", handler);
68
- resolve();
69
- };
70
- provider.on("synced", handler);
71
- });
72
- }
73
- removeProvider(name) {
74
- const provider = this._providers.get(name);
75
- if (!provider) {
76
- throw new Error(`No provider for room ${name}`);
77
- }
78
- provider.destroy();
79
- this._providers.delete(name);
80
- }
81
- getProvider(name) {
82
- return this._providers.get(name);
83
- }
84
- serverTimestamp() {
85
- return Date.now() - this.serverTimeOffset;
86
- }
87
- sendStatelessToClient(room, clientId, data) {
88
- const provider = this._providers.get(room);
89
- if (!provider) {
90
- throw new Error(`No provider for room ${room}`);
91
- }
92
- provider.sendStateless(JSON.stringify({ to: clientId, data }));
93
- }
94
- sendStatelessToRoom(room, data, self = false) {
95
- const provider = this._providers.get(room);
96
- if (!provider) {
97
- throw new Error(`No provider for room ${room}`);
98
- }
99
- provider.sendStateless(JSON.stringify({ data, self }));
100
- }
101
- async mediaUpload(blob) {
102
- try {
103
- const uploadData = await sendMediaUpload(blob, {
104
- apiUrl: this.apiUrl,
105
- appToken: this.token,
106
- });
107
- const { id } = uploadData;
108
- const etags = await getETags(blob, uploadData);
109
- const { url } = await uploadMedia({ id, etags }, { apiUrl: this.apiUrl, appToken: this.token });
110
- return { url, id };
111
- }
112
- catch (error) {
113
- throw new Error(`Error while uploading media: ${errorMessage(error)}`);
114
- }
115
- }
116
- }
package/dist/tasks.d.ts DELETED
@@ -1,43 +0,0 @@
1
- export interface Answer<T = any> {
2
- value?: T;
3
- correct: boolean;
4
- }
5
- export interface TaskBase {
6
- id: string;
7
- text: string;
8
- points: number;
9
- metadata?: Record<string, any>;
10
- }
11
- export interface TaskOption {
12
- text: string;
13
- correct: boolean;
14
- }
15
- export interface MultipleChoiceTask extends TaskBase {
16
- type: "multiple-choice";
17
- answers: TaskOption[];
18
- }
19
- export interface SingleChoiceTask extends TaskBase {
20
- type: "single-choice";
21
- answers: TaskOption[];
22
- }
23
- export interface TextTask extends TaskBase {
24
- type: "text";
25
- answer: string;
26
- }
27
- export interface TextSurveyTask extends TaskBase {
28
- type: "text-survey";
29
- }
30
- export interface NumericTask extends TaskBase {
31
- type: "numeric";
32
- answer: number;
33
- }
34
- export interface PhotoTask extends TaskBase {
35
- type: "photo";
36
- }
37
- export interface VideoTask extends TaskBase {
38
- type: "video";
39
- }
40
- export interface InfoTask extends TaskBase {
41
- type: "info";
42
- }
43
- export type Task = MultipleChoiceTask | SingleChoiceTask | TextTask | NumericTask | TextSurveyTask | PhotoTask | VideoTask | InfoTask;
package/dist/tasks.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,2 +0,0 @@
1
- export * from "./api";
2
- export * from "./tasks";
@@ -1,2 +0,0 @@
1
- export * from "./api";
2
- export * from "./tasks";