@zcomponent/core 1.27.2 → 1.28.0-beta.2

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.
@@ -57,6 +57,10 @@
57
57
  left: 0px;
58
58
  }
59
59
 
60
+ .zcomponent-h-left-safe {
61
+ left: env(safe-area-inset-left, 0px);
62
+ }
63
+
60
64
  .zcomponent-h-center {
61
65
  left: 50%;
62
66
  }
@@ -65,10 +69,18 @@
65
69
  right: 0px;
66
70
  }
67
71
 
72
+ .zcomponent-h-right-safe {
73
+ right: env(safe-area-inset-right, 0px);
74
+ }
75
+
68
76
  .zcomponent-v-top {
69
77
  top: 0px;
70
78
  }
71
79
 
80
+ .zcomponent-v-top-safe {
81
+ top: env(safe-area-inset-top, 0px);
82
+ }
83
+
72
84
  .zcomponent-v-center {
73
85
  top: 50%;
74
86
  }
@@ -77,6 +89,14 @@
77
89
  bottom: 0px;
78
90
  }
79
91
 
92
+ .zcomponent-v-bottom-safe {
93
+ bottom: env(safe-area-inset-bottom, 0px);
94
+ }
95
+
96
+ :xr-overlay .zcomponent-v-top-safe {
97
+ top: 45px;
98
+ }
99
+
80
100
  .zcomponent-hc-v {
81
101
  transform: translate(-50%, 0);
82
102
  }
@@ -209,4 +229,15 @@
209
229
 
210
230
  #zcomponent-cookieconsent-privacypolicy {
211
231
  padding-bottom: 12px;
232
+ }
233
+
234
+ :root {
235
+ --safe-area-inset-left: env(safe-area-inset-left, 0px);
236
+ --safe-area-inset-right: env(safe-area-inset-right, 0px);
237
+ --safe-area-inset-top: env(safe-area-inset-top, 0px);
238
+ --safe-area-inset-bottom: env(safe-area-inset-bottom, 0px);
239
+ }
240
+
241
+ :xr-overlay {
242
+ --safe-area-inset-top: 45px;
212
243
  }
package/lib/cache.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export interface CacheOptions {
2
+ key: string;
3
+ expireMS?: number;
4
+ revalidateMS?: number;
5
+ expireError?: number;
6
+ cacheError?: boolean;
7
+ lifetime?: 'pageload' | 'session' | 'persistent';
8
+ }
9
+ export interface CachePerformer<T> extends CacheOptions {
10
+ perform: () => Promise<T>;
11
+ }
12
+ export declare function cache<T>(opts: CachePerformer<T>): Promise<T>;
package/lib/cache.js ADDED
@@ -0,0 +1,139 @@
1
+ const dbPromise = new Promise((resolve, reject) => {
2
+ const db = indexedDB.open('zee-cache-db');
3
+ db.onupgradeneeded = event => {
4
+ if (!event || !event.target)
5
+ return;
6
+ const db = event.target.result;
7
+ db.createObjectStore('zee-cache', { keyPath: 'key' });
8
+ };
9
+ db.onsuccess = event => {
10
+ if (!event || !event.target)
11
+ return;
12
+ const idb = event.target.result;
13
+ resolve(idb);
14
+ clearExpired();
15
+ };
16
+ db.onerror = event => {
17
+ reject(event);
18
+ };
19
+ });
20
+ const pageLoadByKey = new Map();
21
+ const inflight = new Map();
22
+ function isError(result) {
23
+ return typeof result['err'] === 'string';
24
+ }
25
+ export async function cache(opts) {
26
+ const lifetime = opts.lifetime ?? 'pageload';
27
+ const now = Date.now();
28
+ let entry;
29
+ if (lifetime === 'pageload') {
30
+ entry = pageLoadByKey.get(opts.key);
31
+ if (entry && entry.expireTime && entry.expireTime < now) {
32
+ pageLoadByKey.delete(opts.key);
33
+ entry = undefined;
34
+ }
35
+ }
36
+ else {
37
+ if (lifetime === 'persistent' || window.sessionStorage.getItem(opts.key) === '1') {
38
+ entry = await getItemFromDB(opts.key);
39
+ if (entry && entry.expireTime && entry.expireTime < now) {
40
+ // Will be deleted next open
41
+ entry = undefined;
42
+ }
43
+ }
44
+ }
45
+ const revalidate = entry && opts.revalidateMS && entry.startTime && now - entry.startTime > opts.revalidateMS;
46
+ const revalidateEntry = revalidate ? entry : undefined;
47
+ if (!entry) {
48
+ entry = await inflight.get(opts.key);
49
+ }
50
+ if (!entry || revalidate) {
51
+ const promise = (async () => {
52
+ let ret;
53
+ try {
54
+ const res = await opts.perform();
55
+ ret = {
56
+ key: opts.key,
57
+ expireTime: opts.expireMS ? Date.now() + opts.expireMS : undefined,
58
+ startTime: now,
59
+ result: { val: res },
60
+ };
61
+ }
62
+ catch (err) {
63
+ if (!opts.cacheError)
64
+ throw err;
65
+ ret = {
66
+ key: opts.key,
67
+ expireTime: opts.expireError ? Date.now() + opts.expireError : undefined,
68
+ startTime: now,
69
+ result: { err: err instanceof Error ? err.message : typeof err === 'string' ? err : 'Unknown error' },
70
+ };
71
+ }
72
+ if (lifetime === 'pageload') {
73
+ pageLoadByKey.set(opts.key, ret);
74
+ }
75
+ else {
76
+ await addItemToDB(ret);
77
+ if (lifetime === 'session')
78
+ window.sessionStorage.setItem(opts.key, '1');
79
+ }
80
+ return ret;
81
+ })();
82
+ inflight.set(opts.key, promise);
83
+ promise
84
+ .then(() => {
85
+ inflight.delete(opts.key);
86
+ })
87
+ .catch(() => {
88
+ inflight.delete(opts.key);
89
+ });
90
+ if (!revalidate)
91
+ entry = await promise;
92
+ else
93
+ entry = revalidateEntry;
94
+ }
95
+ if (!entry)
96
+ throw new Error('No value');
97
+ if (isError(entry.result))
98
+ throw new Error(entry.result.err);
99
+ return entry.result.val;
100
+ }
101
+ function handleRequest(r) {
102
+ return new Promise((resolve, reject) => {
103
+ r.onsuccess = () => {
104
+ resolve(r.result);
105
+ };
106
+ r.onerror = event => {
107
+ reject(event);
108
+ };
109
+ });
110
+ }
111
+ async function clearExpired() {
112
+ const db = await dbPromise;
113
+ const os = db.transaction('zee-cache', 'readonly').objectStore('zee-cache');
114
+ const objects = (await handleRequest(os.getAll()));
115
+ const toDelete = new Set();
116
+ const now = Date.now();
117
+ for (const obj of objects) {
118
+ if (obj.expireTime && obj.expireTime < now) {
119
+ toDelete.add(obj.key);
120
+ }
121
+ }
122
+ if (toDelete.size > 0) {
123
+ const os = db.transaction('zee-cache', 'readwrite').objectStore('zee-cache');
124
+ for (const key of toDelete) {
125
+ os.delete(key);
126
+ }
127
+ os.transaction.commit();
128
+ }
129
+ }
130
+ async function addItemToDB(e) {
131
+ const db = await dbPromise;
132
+ const os = db.transaction('zee-cache', 'readwrite').objectStore('zee-cache');
133
+ await handleRequest(os.put(e));
134
+ }
135
+ async function getItemFromDB(key) {
136
+ const db = await dbPromise;
137
+ const os = db.transaction('zee-cache', 'readonly').objectStore('zee-cache');
138
+ return await handleRequest(os.get(key));
139
+ }
@@ -0,0 +1,131 @@
1
+ import { NodeDataCombined } from './data';
2
+ export declare enum ProposedChangeType {
3
+ PROPOSE_NEW_NODE = "proposeNewNode",
4
+ PROPOSE_NEW_BEHAVIOR = "proposeNewBehavior",
5
+ PROPOSE_ENTITY_PROPERTY_CHANGE = "proposeEntityPropertyChange",
6
+ MOVE_NODE = "moveNode",
7
+ DELETE_NODE = "deleteNode",
8
+ DELETE_BEHAVIOR = "deleteBehavior",
9
+ PROPOSE_NEW_LAYER = "proposeNewLayer",
10
+ PROPOSE_DELETE_LAYER = "proposeDeleteLayer",
11
+ PROPOSE_NEW_CLIP = "proposeNewClip",
12
+ PROPOSE_ADD_CLIP_TO_LAYER = "proposeAddClipToLayer",
13
+ PROPOSE_DELETE_LAYER_CLIP = "proposeDeleteLayerClip",
14
+ PROPOSE_ADD_PROPERTY_TRACK = "proposeAddPropertyTrack",
15
+ PROPOSE_ADD_OR_MODIFY_KEYFRAMES = "proposeAddOrModifyKeyframes",
16
+ PROPOSE_DELETE_KEYFRAME = "proposeDeleteKeyframe",
17
+ PROPOSE_MODIFY_LAYER_CLIP = "proposeModifyLayerClip",
18
+ PROPOSE_MODIFY_CLIP = "proposeModifyClip",
19
+ PROPOSE_CHANGE_ENTITY_LABEL = "proposeChangeEntityLabel"
20
+ }
21
+ export interface BaseProposedChange {
22
+ name: ProposedChangeType;
23
+ }
24
+ export interface ProposeNewNode extends BaseProposedChange {
25
+ name: ProposedChangeType.PROPOSE_NEW_NODE;
26
+ data: NodeDataCombined;
27
+ }
28
+ export interface ProposeNewBehavior extends BaseProposedChange {
29
+ name: ProposedChangeType.PROPOSE_NEW_BEHAVIOR;
30
+ id: string;
31
+ label: string;
32
+ parentID: string;
33
+ parentIndex: number;
34
+ type: string;
35
+ }
36
+ export interface ProposeMoveNode extends BaseProposedChange {
37
+ name: ProposedChangeType.MOVE_NODE;
38
+ nodeID: string;
39
+ newParentID: string;
40
+ newParentIndex: number;
41
+ }
42
+ export interface ProposeDeleteNode extends BaseProposedChange {
43
+ name: ProposedChangeType.DELETE_NODE;
44
+ nodeID: string;
45
+ }
46
+ export interface ProposeDeleteBehavior extends BaseProposedChange {
47
+ name: ProposedChangeType.DELETE_BEHAVIOR;
48
+ behaviorID: string;
49
+ }
50
+ export interface ProposeEntityPropertyChange extends BaseProposedChange {
51
+ name: ProposedChangeType.PROPOSE_ENTITY_PROPERTY_CHANGE;
52
+ id: string;
53
+ property: string;
54
+ value: any;
55
+ isConstructorProperty: boolean;
56
+ }
57
+ export interface ProposeNewLayer extends BaseProposedChange {
58
+ name: ProposedChangeType.PROPOSE_NEW_LAYER;
59
+ id: string;
60
+ label: string;
61
+ }
62
+ export interface ProposeDeleteLayer extends BaseProposedChange {
63
+ name: ProposedChangeType.PROPOSE_DELETE_LAYER;
64
+ id: string;
65
+ }
66
+ export interface ProposeNewClip extends BaseProposedChange {
67
+ name: ProposedChangeType.PROPOSE_NEW_CLIP;
68
+ id: string;
69
+ label: string;
70
+ isState: boolean;
71
+ length?: number;
72
+ addToLayerID?: string;
73
+ }
74
+ export interface ProposeAddClipToLayer extends BaseProposedChange {
75
+ name: ProposedChangeType.PROPOSE_ADD_CLIP_TO_LAYER;
76
+ id: string;
77
+ clipID: string;
78
+ layerID: string;
79
+ setAsDefault?: boolean;
80
+ loop?: boolean;
81
+ playAtStart?: boolean;
82
+ }
83
+ export interface ProposeDeleteLayerClip extends BaseProposedChange {
84
+ name: ProposedChangeType.PROPOSE_DELETE_LAYER_CLIP;
85
+ layerID: string;
86
+ layerClipID: string;
87
+ }
88
+ export interface ProposeAddPropertyTrack extends BaseProposedChange {
89
+ id: string;
90
+ name: ProposedChangeType.PROPOSE_ADD_PROPERTY_TRACK;
91
+ clipID: string;
92
+ entityID: string;
93
+ property: string;
94
+ defaultKeyframe?: Keyframe;
95
+ }
96
+ export interface ProposeAddOrModifyKeyframes extends BaseProposedChange {
97
+ name: ProposedChangeType.PROPOSE_ADD_OR_MODIFY_KEYFRAMES;
98
+ clipID: string;
99
+ trackID: string;
100
+ keyframes: {
101
+ id: string;
102
+ value: any;
103
+ time: number;
104
+ easing?: string;
105
+ }[];
106
+ }
107
+ export interface ProposeDeleteKeyframe extends BaseProposedChange {
108
+ name: ProposedChangeType.PROPOSE_DELETE_KEYFRAME;
109
+ clipID: string;
110
+ trackID: string;
111
+ keyframeID: string;
112
+ }
113
+ export interface ProposeModifyLayerClip extends BaseProposedChange {
114
+ name: ProposedChangeType.PROPOSE_MODIFY_LAYER_CLIP;
115
+ layerClipID: string;
116
+ layerID: string;
117
+ setAsDefault?: boolean;
118
+ loop?: boolean;
119
+ playAtStart?: boolean;
120
+ }
121
+ export interface ProposeModifyClip extends BaseProposedChange {
122
+ name: ProposedChangeType.PROPOSE_MODIFY_CLIP;
123
+ clipID: string;
124
+ length?: number;
125
+ }
126
+ export interface ProposeChangeEntityLabel extends BaseProposedChange {
127
+ name: ProposedChangeType.PROPOSE_CHANGE_ENTITY_LABEL;
128
+ id: string;
129
+ label: string;
130
+ }
131
+ export type ProposedChange = ProposeNewNode | ProposeNewBehavior | ProposeEntityPropertyChange | ProposeMoveNode | ProposeDeleteNode | ProposeDeleteBehavior | ProposeNewLayer | ProposeDeleteLayer | ProposeNewClip | ProposeModifyClip | ProposeAddClipToLayer | ProposeDeleteLayerClip | ProposeAddPropertyTrack | ProposeAddOrModifyKeyframes | ProposeDeleteKeyframe | ProposeModifyLayerClip | ProposeChangeEntityLabel;
package/lib/change.js ADDED
@@ -0,0 +1,20 @@
1
+ export var ProposedChangeType;
2
+ (function (ProposedChangeType) {
3
+ ProposedChangeType["PROPOSE_NEW_NODE"] = "proposeNewNode";
4
+ ProposedChangeType["PROPOSE_NEW_BEHAVIOR"] = "proposeNewBehavior";
5
+ ProposedChangeType["PROPOSE_ENTITY_PROPERTY_CHANGE"] = "proposeEntityPropertyChange";
6
+ ProposedChangeType["MOVE_NODE"] = "moveNode";
7
+ ProposedChangeType["DELETE_NODE"] = "deleteNode";
8
+ ProposedChangeType["DELETE_BEHAVIOR"] = "deleteBehavior";
9
+ ProposedChangeType["PROPOSE_NEW_LAYER"] = "proposeNewLayer";
10
+ ProposedChangeType["PROPOSE_DELETE_LAYER"] = "proposeDeleteLayer";
11
+ ProposedChangeType["PROPOSE_NEW_CLIP"] = "proposeNewClip";
12
+ ProposedChangeType["PROPOSE_ADD_CLIP_TO_LAYER"] = "proposeAddClipToLayer";
13
+ ProposedChangeType["PROPOSE_DELETE_LAYER_CLIP"] = "proposeDeleteLayerClip";
14
+ ProposedChangeType["PROPOSE_ADD_PROPERTY_TRACK"] = "proposeAddPropertyTrack";
15
+ ProposedChangeType["PROPOSE_ADD_OR_MODIFY_KEYFRAMES"] = "proposeAddOrModifyKeyframes";
16
+ ProposedChangeType["PROPOSE_DELETE_KEYFRAME"] = "proposeDeleteKeyframe";
17
+ ProposedChangeType["PROPOSE_MODIFY_LAYER_CLIP"] = "proposeModifyLayerClip";
18
+ ProposedChangeType["PROPOSE_MODIFY_CLIP"] = "proposeModifyClip";
19
+ ProposedChangeType["PROPOSE_CHANGE_ENTITY_LABEL"] = "proposeChangeEntityLabel";
20
+ })(ProposedChangeType || (ProposedChangeType = {}));
@@ -57,16 +57,20 @@ export declare class CanvasContext extends Context {
57
57
  */
58
58
  export declare enum HorizontalAlignment {
59
59
  'left' = "left",
60
+ 'leftSafe' = "leftSafe",
60
61
  'center' = "center",
61
- 'right' = "right"
62
+ 'right' = "right",
63
+ 'rightSafe' = "rightSafe"
62
64
  }
63
65
  /**
64
- * Enum representing vertical alignment options: 'top', 'center', 'bottom'.
66
+ * Enum representing vertical alignment options: 'top', 'center', 'bottom', 'topSafe', 'bottomSafe'.
65
67
  */
66
68
  export declare enum VerticalAlignment {
67
69
  'top' = "top",
70
+ 'topSafe' = "topSafe",
68
71
  'center' = "center",
69
- 'bottom' = "bottom"
72
+ 'bottom' = "bottom",
73
+ 'bottomSafe' = "bottomSafe"
70
74
  }
71
75
  /**
72
76
  * Retrieves the canvas element from the `CanvasContext`.
@@ -129,17 +129,21 @@ export class CanvasContext extends Context {
129
129
  export var HorizontalAlignment;
130
130
  (function (HorizontalAlignment) {
131
131
  HorizontalAlignment["left"] = "left";
132
+ HorizontalAlignment["leftSafe"] = "leftSafe";
132
133
  HorizontalAlignment["center"] = "center";
133
134
  HorizontalAlignment["right"] = "right";
135
+ HorizontalAlignment["rightSafe"] = "rightSafe";
134
136
  })(HorizontalAlignment || (HorizontalAlignment = {}));
135
137
  /**
136
- * Enum representing vertical alignment options: 'top', 'center', 'bottom'.
138
+ * Enum representing vertical alignment options: 'top', 'center', 'bottom', 'topSafe', 'bottomSafe'.
137
139
  */
138
140
  export var VerticalAlignment;
139
141
  (function (VerticalAlignment) {
140
142
  VerticalAlignment["top"] = "top";
143
+ VerticalAlignment["topSafe"] = "topSafe";
141
144
  VerticalAlignment["center"] = "center";
142
145
  VerticalAlignment["bottom"] = "bottom";
146
+ VerticalAlignment["bottomSafe"] = "bottomSafe";
143
147
  })(VerticalAlignment || (VerticalAlignment = {}));
144
148
  /**
145
149
  * Retrieves the canvas element from the `CanvasContext`.
@@ -211,23 +215,35 @@ export function classNameForAlignment(h, v) {
211
215
  case HorizontalAlignment.left:
212
216
  names.push('zcomponent-h-left');
213
217
  break;
218
+ case HorizontalAlignment.leftSafe:
219
+ names.push('zcomponent-h-left-safe');
220
+ break;
214
221
  case HorizontalAlignment.center:
215
222
  names.push('zcomponent-h-center');
216
223
  break;
217
224
  case HorizontalAlignment.right:
218
225
  names.push('zcomponent-h-right');
219
226
  break;
227
+ case HorizontalAlignment.rightSafe:
228
+ names.push('zcomponent-h-right-safe');
229
+ break;
220
230
  }
221
231
  switch (v) {
222
232
  case VerticalAlignment.top:
223
233
  names.push('zcomponent-v-top');
224
234
  break;
235
+ case VerticalAlignment.topSafe:
236
+ names.push('zcomponent-v-top-safe');
237
+ break;
225
238
  case VerticalAlignment.center:
226
239
  names.push('zcomponent-v-center');
227
240
  break;
228
241
  case VerticalAlignment.bottom:
229
242
  names.push('zcomponent-v-bottom');
230
243
  break;
244
+ case VerticalAlignment.bottomSafe:
245
+ names.push('zcomponent-v-bottom-safe');
246
+ break;
231
247
  }
232
248
  if (h !== HorizontalAlignment.center && v !== VerticalAlignment.center)
233
249
  names.push('zcomponent-h-v');
@@ -41,6 +41,10 @@ export interface TextAlertOptions {
41
41
  * Text color of the text alert.
42
42
  */
43
43
  textColor?: string;
44
+ /**
45
+ * Delay in milliseconds before showing the text alert.
46
+ */
47
+ delay?: number;
44
48
  }
45
49
  /**
46
50
  * Triggers the display of a text alert.
@@ -39,7 +39,7 @@ export class TextAlertContext extends Context {
39
39
  const timeout = options?.timeout ?? 3000;
40
40
  setTimeout(() => {
41
41
  entry.classList.add('zcomponent-textalert-shown');
42
- }, 30);
42
+ }, options?.delay ?? 30);
43
43
  if (timeout >= 0) {
44
44
  setTimeout(() => {
45
45
  entry.classList.remove('zcomponent-textalert-shown');
@@ -0,0 +1,24 @@
1
+ import { ProposedChange } from './change';
2
+ export interface EditorNewNode {
3
+ id?: string;
4
+ type: string;
5
+ parentID: string;
6
+ parentIndex: number;
7
+ label: string;
8
+ constructorProps?: {
9
+ [id: string]: any;
10
+ };
11
+ props?: {
12
+ [id: string]: any;
13
+ };
14
+ addDefaultChildren?: boolean;
15
+ }
16
+ export interface Editor {
17
+ proposeChanges: (changes: ProposedChange[]) => void;
18
+ addReplaceFiles: (files: {
19
+ name: string;
20
+ data: ArrayBuffer;
21
+ changes?: ProposedChange[];
22
+ }[]) => void;
23
+ createNode: (node: EditorNewNode) => void;
24
+ }
package/lib/editor.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/lib/index.d.ts CHANGED
@@ -16,3 +16,4 @@ export * from './observable';
16
16
  export * from './contexts/environmentcontext';
17
17
  export * from './contexts/audiocontextcontext';
18
18
  export * from './animation';
19
+ export { cache, CacheOptions, CachePerformer } from './cache';
package/lib/index.js CHANGED
@@ -16,6 +16,7 @@ export * from './observable';
16
16
  export * from './contexts/environmentcontext';
17
17
  export * from './contexts/audiocontextcontext';
18
18
  export * from './animation';
19
+ export { cache } from './cache';
19
20
  const link = document.createElement('link');
20
21
  link.setAttribute('rel', 'stylesheet');
21
22
  link.setAttribute('href', new URL('../css/zcomponent.css', import.meta.url).toString());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zcomponent/core",
3
- "version": "1.27.2",
3
+ "version": "1.28.0-beta.2",
4
4
  "description": "The core component model and built-in functionality for Mattercraft.",
5
5
  "author": "Zappar Limited",
6
6
  "license": "Proprietary",