h1v3 0.4.1 → 0.6.1

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 (77) hide show
  1. package/.vscode/settings.json +3 -0
  2. package/dist/browser/client/auth.js +128 -0
  3. package/dist/browser/client/bus.js +1 -0
  4. package/{src/client/web-ui → dist/browser/client}/components/login.js +11 -2
  5. package/dist/browser/client/components/notification.html.js +25 -0
  6. package/dist/browser/client/components/notification.js +27 -0
  7. package/{src/client/web-ui → dist/browser/client}/components/partials/wa-utils.js +1 -0
  8. package/dist/browser/client/context.js +98 -0
  9. package/dist/browser/{event-store/modular.js → client/event-store.js} +22 -14
  10. package/dist/browser/{web → client}/events.js +5 -1
  11. package/{src/client/web/system.js → dist/browser/client/firebase.js} +1 -7
  12. package/dist/browser/client/id.js +37 -0
  13. package/dist/browser/client/logger.js +60 -0
  14. package/dist/browser/client/notifications.js +50 -0
  15. package/dist/browser/{web-ui → client}/system.js +10 -4
  16. package/dist/browser/client/team/invites.js +119 -0
  17. package/dist/browser/client/team/team.js +143 -0
  18. package/dist/browser/client/team/user.js +62 -0
  19. package/package.json +2 -7
  20. package/src/client/context.js +58 -0
  21. package/src/client/index.js +2 -4
  22. package/src/client/node.js +2 -2
  23. package/src/commands/generate-rules.js +56 -39
  24. package/src/commands/vendor.js +86 -23
  25. package/src/configuration.js +116 -0
  26. package/src/event-store/configuration.js +44 -0
  27. package/src/event-store/projections.js +40 -11
  28. package/src/exec-eventstore.js +48 -14
  29. package/src/index.js +20 -4
  30. package/src/load-configuration.js +17 -3
  31. package/src/membership/index.js +5 -3
  32. package/src/membership/team-details/events.js +5 -0
  33. package/src/membership/team-details/projections/current.js +9 -0
  34. package/src/membership/team-details/store.js +30 -0
  35. package/src/membership/team-details/verify-store-paths.js +8 -0
  36. package/src/membership/team-membership/events.js +17 -0
  37. package/src/membership/team-membership/projections/_shared.js +55 -0
  38. package/src/membership/team-membership/projections/details.js +105 -0
  39. package/src/membership/team-membership/projections/inviteToEmail.js +25 -0
  40. package/src/membership/team-membership/projections/members.js +68 -0
  41. package/src/membership/team-membership/store.js +56 -0
  42. package/src/membership/user-profile/events.js +6 -0
  43. package/src/membership/user-profile/projections/current.js +9 -0
  44. package/src/membership/user-profile/store.js +28 -0
  45. package/src/membership/user-teams/events.js +5 -0
  46. package/src/membership/{user-teams-store.js → user-teams/projections/current.js} +2 -24
  47. package/src/membership/user-teams/store.js +27 -0
  48. package/src/membership/userInvites/events.js +12 -0
  49. package/src/membership/userInvites/projections/pending.js +45 -0
  50. package/src/membership/userInvites/store.js +46 -0
  51. package/src/paths.js +5 -0
  52. package/src/rules.js +153 -0
  53. package/src/schema.js +91 -1
  54. package/src/system/main.js +1 -1
  55. package/dist/browser/team/team.js +0 -25
  56. package/dist/browser/web/login.js +0 -48
  57. package/dist/browser/web/system.js +0 -67
  58. package/dist/browser/web-ui/components/login.js +0 -74
  59. package/dist/browser/web-ui/components/notification.html.js +0 -12
  60. package/dist/browser/web-ui/components/notification.js +0 -25
  61. package/dist/browser/web-ui/components/partials/wa-utils.js +0 -17
  62. package/dist/browser/web-ui/errors.js +0 -23
  63. package/scripts/dist-client.js +0 -32
  64. package/src/client/modular.js +0 -81
  65. package/src/client/team-node.js +0 -28
  66. package/src/client/team.js +0 -38
  67. package/src/client/web/events.js +0 -7
  68. package/src/client/web/login.js +0 -48
  69. package/src/client/web-ui/components/login.html.js +0 -44
  70. package/src/client/web-ui/components/notification.html.js +0 -12
  71. package/src/client/web-ui/components/notification.js +0 -25
  72. package/src/client/web-ui/errors.js +0 -23
  73. package/src/client/web-ui/system.js +0 -20
  74. package/src/event-store/initialise.js +0 -28
  75. package/src/membership/membership-store.js +0 -131
  76. package/src/membership/user-profile-store.js +0 -42
  77. /package/dist/browser/{web-ui → client}/components/login.html.js +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ "sarif-viewer.connectToGithubCodeScanning": "off"
3
+ }
@@ -0,0 +1,128 @@
1
+ import { EVENT_EMAIL_AUTH_REQUESTED, EVENT_GOOGLE_AUTH_REQUESTED, EVENT_SIGN_OUT_REQUESTED, EVENT_USER_PROFILE_CHANGED } from "./events.js";
2
+ import { firebase } from "./firebase.js";
3
+ import bus from "./bus.js";
4
+
5
+ let userDataProfileRef, userProfilePathBuildStrategy;
6
+ const subscriptions = [];
7
+
8
+ export function useUserProfiles(userProfilePathBuilder) {
9
+
10
+ userProfilePathBuildStrategy = userProfilePathBuilder;
11
+ initializeAuth();
12
+
13
+ }
14
+
15
+ export function initializeAuth() {
16
+
17
+ const { auth, onAuthStateChanged, GoogleAuthProvider, off, signOut, signInWithPopup, signInWithEmailAndPassword } = firebase.authentication;
18
+ const googleAuth = new GoogleAuthProvider();
19
+
20
+ while(subscriptions.length) subscriptions.pop()();
21
+
22
+ for(const [name, handler] of [
23
+ [EVENT_GOOGLE_AUTH_REQUESTED, handleAuthRequested],
24
+ [EVENT_EMAIL_AUTH_REQUESTED, handleEmailAuthRequested],
25
+ [EVENT_SIGN_OUT_REQUESTED, handleSignOutRequested]
26
+ ]) {
27
+
28
+ subscriptions.push(() => bus.removeEventListener(name, handler));
29
+ bus.addEventListener(name, handler);
30
+
31
+ }
32
+ subscriptions.push(
33
+
34
+ onAuthStateChanged(auth, user => {
35
+
36
+ if (userDataProfileRef) {
37
+
38
+ off(userDataProfileRef);
39
+ userDataProfileRef = null;
40
+
41
+ }
42
+ if (user) {
43
+
44
+ if(userProfilePathBuildStrategy) {
45
+
46
+ userDataProfileRef = ref(db, userProfilePathBuildStrategy(user));
47
+ onValue(userDataProfileRef, snap => {
48
+
49
+ const userDataProfile = snap.val();
50
+ dispatchUserProfile(user, userDataProfile);
51
+
52
+ });
53
+
54
+ } else {
55
+
56
+ dispatchUserProfile(user);
57
+
58
+ }
59
+
60
+ } else {
61
+
62
+ dispatchUserProfile(null);
63
+
64
+ }
65
+
66
+ })
67
+ );
68
+
69
+ function handleSignOutRequested() {
70
+
71
+ signOut(auth);
72
+
73
+ }
74
+
75
+ async function handleEmailAuthRequested(e) {
76
+
77
+ try {
78
+
79
+ await signInWithEmailAndPassword(auth, e.detail?.email, e.detail?.password);
80
+
81
+ } catch (err) {
82
+
83
+ switch (err?.code) {
84
+ case "auth/wrong-password":
85
+ alert("Wrong password");
86
+ break;
87
+ default:
88
+ alert(err?.code || err?.message);
89
+ break;
90
+ }
91
+
92
+ }
93
+ }
94
+
95
+ function handleAuthRequested() {
96
+
97
+ signInWithPopup(auth, googleAuth);
98
+
99
+ }
100
+
101
+ }
102
+
103
+ function dispatchUserProfile(user, userDataProfile) {
104
+
105
+ console.log("Dispatching user profile");
106
+ const displayName = userDataProfile?.displayName || user?.displayName || user?.email;
107
+ const email = user?.email;
108
+ const uid = user?.uid;
109
+ const currentUser = user && Object.freeze({ uid, displayName, email, user: Object.freeze(user) });
110
+ bus.dispatchEvent(new CustomEvent(EVENT_USER_PROFILE_CHANGED, { detail: currentUser }));
111
+
112
+ }
113
+
114
+ export const CURRENT_USER_COMPONENTS = ".h1v3-current-user";
115
+
116
+ export function initializeCurrentUserHooks() {
117
+
118
+ bus.addEventListener(EVENT_USER_PROFILE_CHANGED, ({ detail }) => {
119
+
120
+ for (const el of document.querySelectorAll(CURRENT_USER_COMPONENTS)) {
121
+
122
+ el.currentUser = detail;
123
+
124
+ }
125
+
126
+ });
127
+
128
+ }
@@ -0,0 +1 @@
1
+ export default document;
@@ -1,10 +1,19 @@
1
- import { LitElement, html, bus } from "../system.js";
1
+ import { LitElement, html } from "../system.js";
2
2
  import { styled } from "./partials/wa-utils.js";
3
3
  import { hello, loginButton, loginDialog, signOutButton } from './login.html.js';
4
- import { EVENT_EMAIL_AUTH_REQUESTED, EVENT_GOOGLE_AUTH_REQUESTED, EVENT_SIGN_OUT_REQUESTED } from "../../web/events.js";
4
+ import { EVENT_EMAIL_AUTH_REQUESTED, EVENT_GOOGLE_AUTH_REQUESTED, EVENT_SIGN_OUT_REQUESTED } from "../events.js";
5
+ import { CURRENT_USER_COMPONENTS } from "../auth.js";
6
+ import bus from "../bus.js";
5
7
 
6
8
  class Login extends LitElement {
7
9
 
10
+ constructor() {
11
+ super();
12
+ if (!this.classList.contains(CURRENT_USER_COMPONENTS.substring(1)))
13
+ this.classList.add(CURRENT_USER_COMPONENTS.substring(1));
14
+
15
+ }
16
+
8
17
  static get properties() {
9
18
 
10
19
  return {
@@ -0,0 +1,25 @@
1
+ import { html } from "../system.js";
2
+
3
+ const styles = "opacity: 0.9; margin: 0.5rem; zoom: 0.9";
4
+
5
+ export const errorNotification = ({ message }) => html`
6
+
7
+ <wa-callout variant="danger" style="${styles}; opacity: 1" role="alert">
8
+
9
+ <wa-icon slot="icon" name="circle-exclamation"></wa-icon>
10
+ <strong>${message}</strong>
11
+
12
+ </wa-callout>
13
+
14
+ `;
15
+
16
+ export const infoNotification = ({ message }) => html`
17
+
18
+ <wa-callout style="${styles}" role="alert">
19
+
20
+ <wa-icon slot="icon" name="circle-info"></wa-icon>
21
+ <strong>${message}</strong>
22
+
23
+ </wa-callout>
24
+
25
+ `;
@@ -0,0 +1,27 @@
1
+ import { LitElement } from "../system.js";
2
+ import { errorNotification, infoNotification } from "./notification.html.js";
3
+ import { styled } from "./partials/wa-utils.js";
4
+
5
+ class Notification extends LitElement {
6
+
7
+ static get properties() {
8
+
9
+ return {
10
+
11
+ err: { type: Object },
12
+ info: { type: Object }
13
+
14
+ };
15
+
16
+ }
17
+
18
+ render() {
19
+
20
+ if (this.err)
21
+ return styled(errorNotification(this.err));
22
+ if (this.info)
23
+ return styled(infoNotification(this.info));
24
+ }
25
+
26
+ }
27
+ customElements.define("h1v3-notification", Notification);
@@ -8,6 +8,7 @@ export const styled = (...children) => html`
8
8
  </div>
9
9
  `;
10
10
 
11
+
11
12
  export const dialog = (title, ...children) => html`
12
13
  <wa-dialog label="${title}" light-dismiss class="dialog-light-dismiss">
13
14
 
@@ -0,0 +1,98 @@
1
+ import { eventStore } from "./event-store.js";
2
+ import bus from "./bus.js";
3
+ import { EVENT_ERROR_OCCURRED } from "./events.js";
4
+
5
+ import { user } from "./team/user.js";
6
+ import { userInvites } from "./team/invites.js";
7
+ import { team } from "./team/team.js";
8
+ import { logger } from "./logger.js";
9
+
10
+ function populateParameters(ps, x) {
11
+
12
+ if (!x) return x;
13
+ return Object.entries(ps).reduce((x, [k, v]) => x.replaceAll(`$${k}`, v), x);
14
+
15
+ }
16
+
17
+ function defaultHandleError(err) {
18
+
19
+ bus.dispatchEvent(new CustomEvent(EVENT_ERROR_OCCURRED, { detail: { err } }));
20
+
21
+ }
22
+
23
+ export async function inject({ database, configPath, handleError = defaultHandleError }) {
24
+
25
+ if (!database) throw new Error("Missing database");
26
+ if (!configPath) throw new Error("Missing configPath");
27
+
28
+ const { db, ref, get } = database;
29
+ const snap = await get(ref(db, configPath));
30
+ const config = snap.val();
31
+
32
+ const log = logger(database, config.logs.path);
33
+ const teamMembershipStoreFactory = ({ tid }) => eventStore(database, populateParameters({ tid }, config.team.membership.path));
34
+ const teamDetailsStoreFactory = ({ tid }) => eventStore(database, populateParameters({ tid }, config.team.details.path));
35
+ const userInvitesStoreFactory = ({ emailId }) => eventStore(database, populateParameters({ emailId }, config.userInvites.path));
36
+ const userTeamsStoreFactory = ({ uid }) => eventStore(database, populateParameters({ uid }, config.user.teams.path));
37
+ const userProfileStoreFactory = ({ uid }) => eventStore(database, populateParameters({ uid }, config.user.profile.path));
38
+
39
+ return {
40
+
41
+ user({ uid }) {
42
+
43
+ const userTeamsStore = userTeamsStoreFactory({ uid });
44
+ const userProfileStore = userProfileStoreFactory({ uid });
45
+ const client = user({ userTeamsStore, userProfileStore });
46
+ return makeDisposable(client, [userTeamsStore, userProfileStore]);
47
+
48
+ },
49
+
50
+ invites({ uid, email }) {
51
+
52
+ const userTeamsStore = userTeamsStoreFactory({ uid });
53
+ const userInvitesStore = userInvitesStoreFactory({ emailId: btoa(email) });
54
+ const client = userInvites({ email, uid, userInvitesStore, teamMembershipStoreFactory, userTeamsStore });
55
+ return makeDisposable(client, [client, userTeamsStore, userInvitesStore]);
56
+
57
+ },
58
+
59
+ team({ tid }) {
60
+
61
+ const teamMembershipStore = teamMembershipStoreFactory({ tid });
62
+ const teamDetailsStore = teamDetailsStoreFactory({ tid });
63
+ const client = team({ teamMembershipStore, userInvitesStoreFactory, teamDetailsStore, userTeamsStoreFactory, handleError });
64
+ return makeDisposable(client, [teamMembershipStore, teamDetailsStore]);
65
+
66
+ },
67
+
68
+ log(sharedAttributes) {
69
+
70
+ return log.context(sharedAttributes);
71
+
72
+ }
73
+
74
+ };
75
+
76
+ }
77
+
78
+ function makeDisposable(client, disposables) {
79
+
80
+ const dispose = once(...disposables.map(x => x.dispose.bind(x)));
81
+ return Object.assign(client, { dispose });
82
+
83
+ }
84
+
85
+ function once(...strategies) {
86
+
87
+ let done = false;
88
+ return (...args) => {
89
+
90
+ if (done) return;
91
+ done = true;
92
+ if (!strategies?.length) return;
93
+ if (strategies.length ===1) return strategies[0](...args);
94
+ return strategies.map(s => s(...args));
95
+
96
+ }
97
+
98
+ }
@@ -1,17 +1,18 @@
1
- function newEventId(eventType) {
1
+ import { timeId } from "./id.js";
2
2
 
3
- return `${Date.now()}-${Math.random().toString().substring(2)}-${eventType}`;
3
+ const newEventId = eventType => `${timeId()}-${eventType}`;
4
4
 
5
- }
5
+ export const PROJECTIONS = "_p";
6
+ export const EVENTS = "_e";
6
7
 
7
- export function eventStore(firebase, path) {
8
+ export function eventStore(database, path) {
8
9
 
9
- const { db, ref, onValue, get, set } = firebase;
10
+ const { db, ref, onValue, get, set } = database;
10
11
  for (const required of ["db", "ref", "onValue", "get", "set"])
11
- if (!firebase[required]) throw new Error(`Missing required firebase.${required}`);
12
+ if (!database[required]) throw new Error(`Missing required database.${required}`);
12
13
 
13
- const eventsPath = `${path}/events`;
14
- const projectionsPath = `${path}/projections`;
14
+ const eventsPath = `${path}/${EVENTS}`;
15
+ const projectionsPath = `${path}/${PROJECTIONS}`;
15
16
 
16
17
  const subscriptions = {};
17
18
 
@@ -30,7 +31,7 @@ export function eventStore(firebase, path) {
30
31
 
31
32
  async function unsubscribeAll() {
32
33
 
33
- while(Object.keys(subscriptions).length) {
34
+ while (Object.keys(subscriptions).length) {
34
35
 
35
36
  await Promise.all(
36
37
  Object.keys(subscriptions).map(unsubscribe)
@@ -41,41 +42,48 @@ export function eventStore(firebase, path) {
41
42
  }
42
43
 
43
44
  return {
45
+
44
46
  async record(eventType, payload) {
45
47
 
46
48
  const eid = newEventId(eventType);
47
- const data = { type: eventType, payload };
49
+ const data = { type: eventType, payload, meta: { when: new Date().toISOString() } };
48
50
  await set(ref(db, `${eventsPath}/${eid}`), data);
49
51
 
50
52
  },
53
+
51
54
  async getProjection(name) {
52
55
 
53
56
  const snap = await get(ref(db, `${projectionsPath}/${name}`));
54
57
  return snap.val();
55
58
 
56
59
  },
57
- onProjectionValue(name, callback) {
60
+
61
+ onProjectionValue(name, callback, cancelCallback) {
58
62
 
59
63
  const query = ref(db, `${projectionsPath}/${name}`);
60
64
  console.log("Subscribing to", query.toString());
61
- subscriptions[name] = onValue(query, callback);
65
+ subscriptions[name] = onValue(query, callback, cancelCallback);
62
66
 
63
67
  },
68
+
64
69
  async offProjection(name) {
65
70
 
66
71
  await unsubscribe(name);
67
72
 
68
73
  },
74
+
69
75
  async dispose() {
70
76
 
71
- await unsubscribeAll();
77
+ await unsubscribeAll();
72
78
 
73
79
  },
80
+
74
81
  get path() {
75
82
 
76
83
  return path;
77
84
 
78
85
  }
86
+
79
87
  };
80
88
 
81
- }
89
+ }
@@ -1,7 +1,11 @@
1
1
  export const EVENT_ERROR_OCCURRED = "h1v3:error-occurred";
2
2
 
3
+ export const EVENT_INFO_AVAILABLE = "h1v3:info-available";
4
+
3
5
  export const EVENT_SIGN_OUT_REQUESTED = "h1v3:sign-out-requested";
4
6
 
5
7
  export const EVENT_EMAIL_AUTH_REQUESTED = "h1v3:email-auth-requested";
6
8
 
7
- export const EVENT_GOOGLE_AUTH_REQUESTED = "h1v3:google-auth-requested";
9
+ export const EVENT_GOOGLE_AUTH_REQUESTED = "h1v3:google-auth-requested";
10
+
11
+ export const EVENT_USER_PROFILE_CHANGED = "h1v3:user-profile-changed";
@@ -58,10 +58,4 @@ export const firebase = {
58
58
  onValue,
59
59
  off
60
60
  }
61
- }
62
-
63
- export const bus = document;
64
-
65
- // h1v3
66
- import { registerLoginHandlers } from "./login.js";
67
- registerLoginHandlers(bus, firebase);
61
+ }
@@ -0,0 +1,37 @@
1
+ function rand62(n) {
2
+
3
+ const out = [];
4
+ const bytes = new Uint8Array(n * 2);
5
+ do {
6
+
7
+ crypto.getRandomValues(bytes);
8
+ for (const b of bytes) {
9
+
10
+ if (b < 248) { // 248 is the largest multiple of 62 below 256
11
+
12
+ const x = b % 62;
13
+ out.push(
14
+ String.fromCharCode(x < 10 ? 48 + x : x < 36 ? 97 + x - 10 : 65 + x - 36)
15
+ );
16
+ if (out.length === n) return out.join('');
17
+
18
+ }
19
+
20
+ }
21
+
22
+ } while (true);
23
+
24
+ }
25
+
26
+ export const timeId = () => `${Date.now()}-${rand62(21)}`;
27
+
28
+ export const generateSpanId = () => generateLowerHex(8);
29
+
30
+ export const generateTraceId = () => generateLowerHex(16);
31
+
32
+ function generateLowerHex(byteLength) {
33
+
34
+ const bytes = crypto.getRandomValues(new Uint8Array(byteLength));
35
+ return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
36
+
37
+ }
@@ -0,0 +1,60 @@
1
+ import { timeId, generateSpanId, generateTraceId } from "./id.js";
2
+
3
+ function munge(attributes) {
4
+
5
+ if(!attributes) return attributes;
6
+ if (!(typeof attributes === "object")) return attributes;
7
+ return Object.entries(attributes).reduce((agg, [key, value]) => ({
8
+ ...agg,
9
+ [key.replaceAll(".", "__")]: munge(value)
10
+ }), {});
11
+
12
+ }
13
+
14
+ export function logger(database, path, defaultAttributes) {
15
+
16
+ const { db, ref, set } = database;
17
+ const record = data => {
18
+
19
+ const refPath = path.replace("$id", timeId());
20
+ console.log("Logging", data, "to", refPath);
21
+ return set(ref(db, refPath), data);
22
+
23
+ };
24
+
25
+ async function recordLog(trace_id, level, sharedAttributes, { body, parent_id, attributes }) {
26
+
27
+ const span_id = generateSpanId();
28
+ console.log(defaultAttributes, sharedAttributes, attributes);
29
+ const data = {
30
+ body,
31
+ trace_id,
32
+ span_id,
33
+ severity_text: level,
34
+ time_client_ms: Date.now(),
35
+ attributes: munge({ ...defaultAttributes, ...sharedAttributes, ...attributes })
36
+ };
37
+ if (parent_id) data.parent_id = parent_id;
38
+ await record(data);
39
+
40
+ }
41
+
42
+ return {
43
+
44
+ context(sharedAttributes) {
45
+
46
+ const id = generateTraceId();
47
+ return {
48
+ id,
49
+ trace: recordLog.bind(this, id, "TRACE", sharedAttributes),
50
+ debug: recordLog.bind(this, id, "DEBUG", sharedAttributes),
51
+ info: recordLog.bind(this, id, "INFO", sharedAttributes),
52
+ warn: recordLog.bind(this, id, "WARN", sharedAttributes),
53
+ error: recordLog.bind(this, id, "ERROR", sharedAttributes),
54
+ fatal: recordLog.bind(this, id, "FATAL", sharedAttributes)
55
+ };
56
+
57
+ }
58
+ };
59
+
60
+ }
@@ -0,0 +1,50 @@
1
+ import { EVENT_ERROR_OCCURRED, EVENT_INFO_AVAILABLE } from "./events.js";
2
+ import bus from "./bus.js";
3
+
4
+ const container = document.createElement("ASIDE");
5
+ container.style.position = "fixed";
6
+ container.style.top = "0px";
7
+ container.style.right = "0px";
8
+ container.style.maxWidth = "40rem";
9
+ container.style.zIndex = 9999;
10
+
11
+ document.body.appendChild(container);
12
+
13
+ export function initializeNotifications() {
14
+
15
+ bus.addEventListener(EVENT_INFO_AVAILABLE, ({ detail }) => {
16
+
17
+ if (detail?.message) {
18
+
19
+ const notification = buildNotification();
20
+ notification.info = detail;
21
+
22
+ }
23
+
24
+ });
25
+
26
+ }
27
+
28
+ export function initializeErrorHandling() {
29
+
30
+ bus.addEventListener(EVENT_ERROR_OCCURRED, ({ detail: { err } }) => {
31
+
32
+ if (err) {
33
+
34
+ const notification = buildNotification();
35
+ notification.err = err;
36
+
37
+ }
38
+
39
+ });
40
+
41
+ }
42
+
43
+ function buildNotification() {
44
+
45
+ const notification = document.createElement("h1v3-notification");
46
+ container.appendChild(notification);
47
+ setTimeout(() => notification.remove(), 5000);
48
+ return notification;
49
+
50
+ }
@@ -1,7 +1,8 @@
1
- export * from "../web/system.js";
2
-
3
1
  export const waDist = "/vendor/@shoelace-style/webawesome-pro@3.0.0-beta.6/dist";
4
2
 
3
+ // firebase
4
+ export * from "./firebase.js";
5
+
5
6
  // vendor: webawesome
6
7
  import "/vendor/@shoelace-style/webawesome-pro@3.0.0-beta.6/dist/components/button/button.js";
7
8
  import "/vendor/@shoelace-style/webawesome-pro@3.0.0-beta.6/dist/components/input/input.js";
@@ -12,9 +13,14 @@ import "/vendor/@shoelace-style/webawesome-pro@3.0.0-beta.6/dist/components/dial
12
13
  import "/vendor/@shoelace-style/webawesome-pro@3.0.0-beta.6/dist/components/callout/callout.js";
13
14
 
14
15
  // vendor: lit
15
- export { html, LitElement } from "/vendor/lit@3.3.1/dist/lit-core.min.js";
16
+ export { html, LitElement, css, render } from "/vendor/lit@3.3.1/dist/lit-core.min.js";
16
17
 
17
18
  // h1v3
18
- import "./errors.js";
19
19
  import "./components/notification.js";
20
20
  import "./components/login.js";
21
+ import { initializeErrorHandling, initializeNotifications } from "./notifications.js";
22
+ import { initializeAuth, initializeCurrentUserHooks } from "./auth.js";
23
+ initializeErrorHandling();
24
+ initializeNotifications();
25
+ initializeCurrentUserHooks();
26
+ initializeAuth();