insite-users-client 1.0.27 → 2.0.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/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "insite-users-client",
3
- "version": "1.0.27",
3
+ "version": "2.0.0",
4
4
  "description": "inSite users client side",
5
5
  "type": "module",
6
- "main": "./lib/index.js",
7
- "module": "./lib/index.js",
8
- "packageManager": "bun@1.1.9",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "packageManager": "bun@1.1.26",
9
9
  "scripts": {
10
- "test": "echo \"Error: no test specified\" && exit 1"
10
+ "test": "echo \"Error: no test specified\" && exit 1",
11
+ "build": "bun .conveyer.js",
12
+ "postbuild": "tsc -p ."
11
13
  },
12
14
  "repository": {
13
15
  "type": "git",
@@ -21,9 +23,13 @@
21
23
  "author": "Eugene Nesvetaev <dev@nesvet.dev> (https://nesvet.dev/)",
22
24
  "license": "MIT",
23
25
  "dependencies": {
24
- "insite-subscriptions-client": "^1"
26
+ "@nesvet/n": "^1.1.7",
27
+ "insite-common": "^2",
28
+ "insite-subscriptions-client": "^2"
25
29
  },
26
30
  "devDependencies": {
27
- "@nesvet/eslint-config": "^1"
31
+ "@nesvet/conveyer": "^2.2.4",
32
+ "@nesvet/eslint-config": "^2.0.25",
33
+ "typescript": "^5.5.4"
28
34
  }
29
35
  }
@@ -0,0 +1,75 @@
1
+ import {
2
+ SubscriptionGroup,
3
+ type SubscriptionGroupOptions,
4
+ type SubscriptionMapWithSubscription,
5
+ type SubscriptionObjectWithSubscription
6
+ } from "insite-subscriptions-client";
7
+ import { handleExtendedOrgs, handleOrgs, handleOrgsBeforeSubscribe } from "./orgs";
8
+ import { handleRoles } from "./roles";
9
+ import { handleUser } from "./user";
10
+ import { handleExtendedUsers, handleUsers } from "./users";
11
+
12
+
13
+ const basisDefinitions = [
14
+ [ "orgs", "map", handleOrgs, handleOrgsBeforeSubscribe ],
15
+ [ "users", "map", handleUsers ],
16
+ [ "user", [ true ], handleUser ]
17
+ ];
18
+
19
+ const extendedDefinitions = [
20
+ [ "roles", "map", handleRoles ],
21
+ [ "extendedUsers", "map", "users.extended", handleExtendedUsers, true ],
22
+ [ "extendedOrgs", "map", "orgs.extended", handleExtendedOrgs, true ]
23
+ ];
24
+
25
+ export class UsersSubscriptionGroup extends SubscriptionGroup<typeof basisDefinitions | typeof extendedDefinitions> {
26
+ constructor(options: SubscriptionGroupOptions) {
27
+ super(basisDefinitions, options);
28
+
29
+ }
30
+
31
+ isExtended: boolean | null = false;
32
+
33
+ extend() {
34
+
35
+ if (this.isExtended === false) {
36
+ this.isExtended = null;
37
+
38
+ return this.attach(extendedDefinitions).then(() => {
39
+
40
+ this.isExtended = true;
41
+
42
+ });
43
+ }
44
+
45
+ return null;
46
+ }
47
+
48
+ unextend() {
49
+
50
+ if (this.isExtended) {
51
+ this.isExtended = false;
52
+
53
+ this.detach([ "roles", "extendedUsers", "extendedOrgs" ]);
54
+ }
55
+
56
+ }
57
+
58
+
59
+ static handleValues({
60
+ orgs,
61
+ users,
62
+ user
63
+ }: {
64
+ orgs: SubscriptionMapWithSubscription;
65
+ users: SubscriptionMapWithSubscription;
66
+ user: SubscriptionObjectWithSubscription;
67
+ }, options: SubscriptionGroupOptions) {
68
+ return new SubscriptionGroup([
69
+ [ "orgs", orgs, handleOrgs, handleOrgsBeforeSubscribe ],
70
+ [ "users", users, handleUsers ],
71
+ [ "user", user, handleUser ]
72
+ ], options);
73
+ }
74
+
75
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export type { NullOrg, Org, OrgExtended, Orgs, OrgsExtended } from "./orgs";
2
+ export type { Role, Roles } from "./roles";
3
+ export type { CurrentUser } from "./user";
4
+ export type { User, UserExtended, Users, UsersExtended } from "./users";
5
+ export * from "./UsersSubscriptionGroup";
package/src/orgs.ts ADDED
@@ -0,0 +1,110 @@
1
+ import { getAll } from "@nesvet/n";
2
+ import type { SubscriptionMapUpdated, SubscriptionMapWithSubscription } from "insite-subscriptions-client";
3
+ import type { User } from "./users";
4
+ import type { UsersSubscriptionGroup } from "./UsersSubscriptionGroup";
5
+
6
+
7
+ export type Org = {
8
+ _id: string;
9
+ title: string;
10
+ isOrg: true;
11
+ users: { sorted: User[] } & Set<User>;
12
+ };
13
+
14
+ export type NullOrg = { _id: null } & Omit<Org, "_id">;
15
+
16
+ type OrgExtension = {
17
+ _id: string;
18
+ owners: string[];
19
+ slaveOrgs: string[];
20
+ note: string;
21
+ };
22
+
23
+ export type OrgExtended = {
24
+ owners?: (OrgExtended | User)[];
25
+ slaveOrgs?: OrgExtended[];
26
+ note?: string;
27
+ _l?: number;
28
+ } & Org;
29
+
30
+ type OrgsExtra = {
31
+ null: NullOrg;
32
+ };
33
+
34
+ export type Orgs = OrgsExtra & SubscriptionMapWithSubscription<Org>;
35
+
36
+ export type OrgsExtended = {
37
+ sortedHierarchically?: OrgExtended[];
38
+ } & OrgsExtra & SubscriptionMapWithSubscription<OrgExtended>;
39
+
40
+
41
+ export function handleOrgsBeforeSubscribe(orgs: Orgs) {
42
+ orgs.null = {
43
+ _id: null,
44
+ title: "",
45
+ isOrg: true,
46
+ users: Object.assign(new Set<User>(), { sorted: [] })
47
+ };
48
+
49
+ }
50
+
51
+ /** @this UsersSubscriptionGroup */
52
+ export function handleOrgs(this: UsersSubscriptionGroup, updated: null | SubscriptionMapUpdated<Org>) {
53
+ if (updated)
54
+ for (const org of updated.added) {
55
+ org.isOrg = true;
56
+
57
+ org.users = Object.assign(new Set<User>(), { sorted: [] });
58
+ }
59
+ else {
60
+ this.values.orgs.null.users.clear();
61
+ this.values.orgs.null.users.sorted.length = 0;
62
+ }
63
+
64
+ }
65
+
66
+ /** @this UsersSubscriptionGroup */
67
+ export function handleExtendedOrgs(this: UsersSubscriptionGroup, updated: null | SubscriptionMapUpdated<OrgExtension>) {
68
+
69
+ const orgs = this.values.orgs as OrgsExtended;
70
+
71
+ if (updated) {
72
+ const { users, extendedOrgs } = this.values;
73
+
74
+ for (const orgExtension of updated) {
75
+ const org = orgs.get(orgExtension._id)!;
76
+
77
+ org.owners = orgExtension.owners.map(_id => users.get(_id) || orgs.get(_id));
78
+ org.slaveOrgs = getAll(orgs, orgExtension.slaveOrgs, true);
79
+ org.note = orgExtension.note;
80
+ org._l = 0;
81
+ }
82
+
83
+ const sortedHierarchically = [];
84
+
85
+ for (const orgExtension of extendedOrgs.sorted) {
86
+ const org = orgs.get(orgExtension._id)!;
87
+
88
+ for (const slaveOrg of org.slaveOrgs!)
89
+ slaveOrg._l = org._l! + 1;
90
+
91
+ sortedHierarchically.push(org);
92
+ }
93
+
94
+ orgs.sortedHierarchically = sortedHierarchically;
95
+
96
+ if (this.isLoaded) {
97
+ this.items.users.emitUpdate();
98
+ this.items.orgs.emitUpdate(updated);
99
+ }
100
+ } else {
101
+ for (const org of orgs.sorted) {
102
+ delete org.owners;
103
+ delete org.slaveOrgs;
104
+ delete org.note;
105
+ delete org._l;
106
+ }
107
+ delete orgs.sortedHierarchically;
108
+ }
109
+
110
+ }
package/src/roles.ts ADDED
@@ -0,0 +1,35 @@
1
+ import { getAll } from "@nesvet/n";
2
+ import type { SubscriptionMapUpdated, SubscriptionMapWithSubscription } from "insite-subscriptions-client";
3
+ import type { UsersSubscriptionGroup } from "./UsersSubscriptionGroup";
4
+
5
+
6
+ export type Role = {
7
+ _id: string;
8
+ ownInvolves: Role[];
9
+ involves: Role[];
10
+ _l: number;
11
+ };
12
+
13
+ export type Roles = SubscriptionMapWithSubscription<Role>;
14
+
15
+
16
+ /** @this UsersSubscriptionGroup */
17
+ export function handleRoles(this: UsersSubscriptionGroup, updated: null | SubscriptionMapUpdated<Role>) {
18
+ if (updated) {
19
+ const roles = this.values.roles as Roles;
20
+
21
+ for (const role of updated) {
22
+ role.ownInvolves = getAll(roles, role.ownInvolves as unknown as string[], true);
23
+ role.involves = getAll(roles, role.involves as unknown as string[], true);
24
+ role._l = 0;
25
+ }
26
+
27
+ for (const role of roles.sorted)
28
+ for (const involvedRole of role.ownInvolves)
29
+ involvedRole._l = role._l + 1;
30
+
31
+ if (this.isLoaded)
32
+ this.items.users.emitUpdate(updated);
33
+ }
34
+
35
+ }
@@ -1,5 +1,22 @@
1
+ import type { Abilities, AbilitiesSchema } from "insite-common";
2
+ import type { Org } from "./orgs";
3
+ import type { User, UserExtended } from "./users";
4
+ import type { UsersSubscriptionGroup } from "./UsersSubscriptionGroup";
5
+
6
+
7
+ export type CurrentUser<AS extends AbilitiesSchema = AbilitiesSchema> = {
8
+ abilities: Abilities<AS>;
9
+ sessionId?: string;
10
+ slaveIds: string[];
11
+ slavesSnapshot: string;
12
+ slaves: (Org | User)[];
13
+ slaveUsers: User[];
14
+ slaveOrgs: Org[];
15
+ } & UserExtended;
16
+
17
+
1
18
  /** @this UsersSubscriptionGroup */
2
- export function handleUser(user) {
19
+ export function handleUser(this: UsersSubscriptionGroup, user: CurrentUser) {
3
20
  if (user) {
4
21
 
5
22
  const slavesSnapshot = user.slaveIds.join(",");
package/src/users.ts ADDED
@@ -0,0 +1,125 @@
1
+ import { removeOne } from "@nesvet/n";
2
+ import type { SubscriptionMapUpdated, SubscriptionMapWithSubscription } from "insite-subscriptions-client";
3
+ import type { NullOrg, Org, Orgs } from "./orgs";
4
+ import type { Role } from "./roles";
5
+ import type { CurrentUser } from "./user";
6
+ import type { UsersSubscriptionGroup } from "./UsersSubscriptionGroup";
7
+
8
+
9
+ export type User = {
10
+ _id: string;
11
+ isUser: true;
12
+ email: string;
13
+ name: {
14
+ first: string;
15
+ middle: string;
16
+ last: string;
17
+ };
18
+ orgId: string;
19
+ job: string;
20
+ initials: string;
21
+ displayLabel: string;
22
+ avatarUrl: string;
23
+ isOnline: boolean;
24
+ org: NullOrg | Org;
25
+ };
26
+
27
+ type UserExtension = {
28
+ _id: string;
29
+ roleIds: string[];
30
+ };
31
+
32
+ export type UserExtended = {
33
+ roles?: Role;
34
+ } & User;
35
+
36
+ export type Users = SubscriptionMapWithSubscription<User>;
37
+
38
+ export type UsersExtended = SubscriptionMapWithSubscription<UserExtended>;
39
+
40
+
41
+ /** @this UsersSubscriptionGroup */
42
+ export function handleUsers(this: UsersSubscriptionGroup, updated: null | SubscriptionMapUpdated<User>) {
43
+ if (updated) {
44
+ const users = this.values.users as Users;
45
+ const currentUser = this.values.user as CurrentUser;
46
+ const orgs = this.values.orgs as Orgs;
47
+
48
+ if (users.get(currentUser._id) !== currentUser) {
49
+ users.set(currentUser._id, currentUser);
50
+ users.sorted[users.sorted.findIndex(user => user._id === currentUser._id)] = currentUser;
51
+ }
52
+ const updatedUserIndex = updated.findIndex(user => user._id === currentUser._id);
53
+
54
+ if (~updatedUserIndex)
55
+ updated[updatedUserIndex] = currentUser;
56
+
57
+ const addedUserIndex = updated.added.findIndex(user => user._id === currentUser._id);
58
+
59
+ if (~addedUserIndex)
60
+ updated.added[updatedUserIndex] = currentUser;
61
+
62
+ for (const user of updated.added)
63
+ user.isUser = true;
64
+
65
+ let shouldUpdateUser;
66
+ const orgsToSortUsers = new Set<NullOrg | Org>();
67
+
68
+ for (const user of updated) {
69
+ const org = orgs.get(user.orgId) ?? orgs.null;
70
+
71
+ if (user.org !== org) {
72
+ if (user.org) {
73
+ user.org.users.delete(user);
74
+ removeOne(user.org.users.sorted, user);
75
+ }
76
+ user.org = org;
77
+ user.org.users.add(user);
78
+ user.org.users.sorted.push(user);
79
+
80
+ orgsToSortUsers.add(user.org);
81
+ }
82
+
83
+ if (user === currentUser)
84
+ shouldUpdateUser = true;
85
+
86
+ }
87
+
88
+ for (const org of orgsToSortUsers)
89
+ org.users.sorted.sort(users.sortCompareFunction!);
90
+
91
+ if (updated.deleted.length)
92
+ for (const org of [ ...orgs.sorted, orgs.null ])
93
+ for (const user of org.users)
94
+ if (!users.has(user._id)) {
95
+ org.users.delete(user);
96
+ removeOne(org.users.sorted, user);
97
+ }
98
+
99
+ if (this.isLoaded) {
100
+ if (shouldUpdateUser)
101
+ this.items.user.emitUpdate();
102
+ this.items.orgs.emitUpdate();
103
+ }
104
+ }
105
+
106
+ }
107
+
108
+ /** @this UsersSubscriptionGroup */
109
+ export function handleExtendedUsers(this: UsersSubscriptionGroup, updated: null | SubscriptionMapUpdated<UserExtension>) {
110
+
111
+ const users = this.values.users as UsersExtended;
112
+
113
+ if (updated) {
114
+ const { roles } = this.values;
115
+
116
+ for (const userExtension of updated) {
117
+ const user = users.get(userExtension._id)!;
118
+
119
+ user.roles = roles.getAll(userExtension.roleIds);
120
+ }
121
+ } else
122
+ for (const user of users.sorted)
123
+ delete user.roles;
124
+
125
+ }
package/bun.lockb DELETED
Binary file
@@ -1,57 +0,0 @@
1
- import { SubscriptionGroup } from "insite-subscriptions-client";
2
- import { handleExtendedOrgs, handleOrgs, handleOrgsBeforeSubscribe } from "./orgs";
3
- import { handleRoles } from "./roles";
4
- import { handleUser } from "./user";
5
- import { handleExtendedUsers, handleUsers } from "./users";
6
-
7
-
8
- export class UsersSubscriptionGroup extends SubscriptionGroup {
9
- constructor(options) {
10
- super([
11
- [ "orgs", "map", handleOrgs, handleOrgsBeforeSubscribe ],
12
- [ "users", "map", handleUsers ],
13
- [ "user", [ true ], handleUser ]
14
- ], options);
15
-
16
- }
17
-
18
- isExtended = false;
19
-
20
- extend() {
21
-
22
- if (this.isExtended === false) {
23
- this.isExtended = null;
24
-
25
- return this.attach([
26
- [ "roles", "map", handleRoles ],
27
- [ "extendedUsers", "map", "users.extended", handleExtendedUsers, true ],
28
- [ "extendedOrgs", "map", "orgs.extended", handleExtendedOrgs, true ]
29
- ]).then(() => {
30
-
31
- this.isExtended = true;
32
-
33
- });
34
- }
35
-
36
- }
37
-
38
- unextend() {
39
-
40
- if (this.isExtended) {
41
- this.isExtended = false;
42
-
43
- this.detach([ "roles", "extendedUsers", "extendedOrgs" ]);
44
- }
45
-
46
- }
47
-
48
-
49
- static handleValues({ orgs, users, user }, options) {
50
- return new SubscriptionGroup([
51
- [ "orgs", orgs, handleOrgs, handleOrgsBeforeSubscribe ],
52
- [ "users", users, handleUsers ],
53
- [ "user", user, handleUser ]
54
- ], options);
55
- }
56
-
57
- }
package/lib/index.js DELETED
@@ -1 +0,0 @@
1
- export * from "./UsersSubscriptionGroup";
package/lib/orgs.js DELETED
@@ -1,72 +0,0 @@
1
- export function handleOrgsBeforeSubscribe(orgs) {
2
-
3
- orgs.null = {
4
- _id: null,
5
- title: "",
6
- isOrg: true,
7
- users: Object.assign(new Set(), { sorted: [] })
8
- };
9
-
10
- }
11
-
12
- /** @this UsersSubscriptionGroup */
13
- export function handleOrgs(updated) {
14
- if (updated)
15
- for (const org of updated.added) {
16
- org.isOrg = true;
17
-
18
- org.users = Object.assign(new Set(), { sorted: [] });
19
- }
20
- else {
21
- const nullOrgUsers = this.values.orgs.null.users;
22
- nullOrgUsers.clear();
23
- nullOrgUsers.sorted.length = 0;
24
- }
25
-
26
- }
27
-
28
- /** @this UsersSubscriptionGroup */
29
- export function handleExtendedOrgs(updated) {
30
-
31
- const { orgs } = this.values;
32
-
33
- if (updated) {
34
- const { users, extendedOrgs } = this.values;
35
-
36
- for (const orgDoc of updated) {
37
- const org = orgs.get(orgDoc._id);
38
-
39
- org.owners = orgDoc.owners.map(_id => users.get(_id) || orgs.get(_id));
40
- org.slaveOrgs = orgs.getAll(orgDoc.slaveOrgs);
41
- org.note = orgDoc.note;
42
- org._l = 0;
43
- }
44
-
45
- const sortedHierarchically = [];
46
-
47
- for (const orgDoc of extendedOrgs.sorted) {
48
- const org = orgs.get(orgDoc._id);
49
-
50
- for (const slaveOrg of org.slaveOrgs)
51
- slaveOrg._l = org._l + 1;
52
-
53
- sortedHierarchically.push(org);
54
- }
55
-
56
- orgs.sortedHierarchically = sortedHierarchically;
57
-
58
- if (this.isLoaded) {
59
- this.items.users.emitUpdate();
60
- this.items.orgs.emitUpdate(updated);
61
- }
62
- } else {
63
- for (const org of orgs.sorted) {
64
- delete org.owners;
65
- delete org.slaveOrgs;
66
- delete org.note;
67
- delete org._l;
68
- }
69
- delete orgs.sortedHierarchically;
70
- }
71
-
72
- }
package/lib/roles.js DELETED
@@ -1,20 +0,0 @@
1
- /** @this UsersSubscriptionGroup */
2
- export function handleRoles(updated) {
3
- if (updated) {
4
- const { roles } = this.values;
5
-
6
- for (const role of updated) {
7
- role.ownInvolves = roles.getAll(role.ownInvolves);
8
- role.involves = roles.getAll(role.involves);
9
- role._l = 0;
10
- }
11
-
12
- for (const role of roles.sorted)
13
- for (const involvedRole of role.ownInvolves)
14
- involvedRole._l = role._l + 1;
15
-
16
- if (this.isLoaded)
17
- this.items.users.emitUpdate(updated);
18
- }
19
-
20
- }
package/lib/users.js DELETED
@@ -1,83 +0,0 @@
1
- /** @this UsersSubscriptionGroup */
2
- export function handleUsers(updated) {
3
- if (updated) {
4
- const { users, user: currentUser, orgs } = this.values;
5
-
6
- if (users.get(currentUser._id) !== currentUser) {
7
- users.set(currentUser._id, currentUser);
8
- users.sorted[users.sorted.findIndex(user => user._id === currentUser._id)] = currentUser;
9
- }
10
- const updatedUserIndex = updated.findIndex(user => user._id === currentUser._id);
11
-
12
- if (~updatedUserIndex)
13
- updated[updatedUserIndex] = currentUser;
14
-
15
- const addedUserIndex = updated.added.findIndex(user => user._id === currentUser._id);
16
-
17
- if (~addedUserIndex)
18
- updated.added[updatedUserIndex] = currentUser;
19
-
20
- for (const user of updated.added)
21
- user.isUser = true;
22
-
23
- let shouldUpdateUser;
24
- const orgsToSortUsers = new Set();
25
-
26
- for (const user of updated) {
27
- const org = orgs.get(user.orgId) ?? orgs.null;
28
-
29
- if (user.org !== org) {
30
- if (user.org) {
31
- user.org.users.delete(user);
32
- user.org.users.sorted.remove(user);
33
- }
34
- user.org = org;
35
- user.org.users.add(user);
36
- user.org.users.sorted.push(user);
37
-
38
- orgsToSortUsers.add(user.org);
39
- }
40
-
41
- if (user === currentUser)
42
- shouldUpdateUser = true;
43
-
44
- }
45
-
46
- for (const org of orgsToSortUsers)
47
- org.users.sorted.sort(users.sortCompareFunction);
48
-
49
- if (updated.deleted.length)
50
- for (const org of orgs.sorted)
51
- for (const user of org.users)
52
- if (!users.has(user._id)) {
53
- org.users.delete(user);
54
- org.users.sorted.remove(user);
55
- }
56
-
57
- if (this.isLoaded) {
58
- if (shouldUpdateUser)
59
- this.items.user.emitUpdate();
60
- this.items.orgs.emitUpdate();
61
- }
62
- }
63
-
64
- }
65
-
66
- /** @this UsersSubscriptionGroup */
67
- export function handleExtendedUsers(updated) {
68
-
69
- const { users } = this.values;
70
-
71
- if (updated) {
72
- const { roles } = this.values;
73
-
74
- for (const userDoc of updated) {
75
- const user = users.get(userDoc._id);
76
-
77
- user.roles = roles.getAll(userDoc.roleIds);
78
- }
79
- } else
80
- for (const user of users.sorted)
81
- delete user.roles;
82
-
83
- }