solid-logic 1.3.17-6a574cd0 → 1.3.17-6e0634d8

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 (123) hide show
  1. package/README.md +2 -2
  2. package/lib/acl/aclLogic.d.ts +3 -30
  3. package/lib/acl/aclLogic.d.ts.map +1 -1
  4. package/lib/acl/aclLogic.js +150 -119
  5. package/lib/acl/aclLogic.js.map +1 -1
  6. package/lib/authn/SolidAuthnLogic.d.ts.map +1 -1
  7. package/lib/authn/SolidAuthnLogic.js +2 -2
  8. package/lib/authn/SolidAuthnLogic.js.map +1 -1
  9. package/lib/chat/chatLogic.d.ts +3 -0
  10. package/lib/chat/chatLogic.d.ts.map +1 -0
  11. package/lib/chat/{ChatLogic.js → chatLogic.js} +82 -86
  12. package/lib/chat/chatLogic.js.map +1 -0
  13. package/lib/inbox/inboxLogic.d.ts +3 -0
  14. package/lib/inbox/inboxLogic.d.ts.map +1 -0
  15. package/lib/inbox/{InboxLogic.js → inboxLogic.js} +59 -64
  16. package/lib/inbox/inboxLogic.js.map +1 -0
  17. package/lib/index.d.ts +6 -11
  18. package/lib/index.d.ts.map +1 -1
  19. package/lib/index.js +5 -38
  20. package/lib/index.js.map +1 -1
  21. package/lib/logic/CustomError.d.ts +4 -0
  22. package/lib/logic/CustomError.d.ts.map +1 -1
  23. package/lib/logic/CustomError.js +17 -1
  24. package/lib/logic/CustomError.js.map +1 -1
  25. package/lib/logic/solidLogic.d.ts +6 -0
  26. package/lib/logic/solidLogic.d.ts.map +1 -0
  27. package/lib/logic/solidLogic.js +92 -0
  28. package/lib/logic/solidLogic.js.map +1 -0
  29. package/lib/logic/solidLogicSingleton.d.ts +1 -2
  30. package/lib/logic/solidLogicSingleton.d.ts.map +1 -1
  31. package/lib/logic/solidLogicSingleton.js +3 -3
  32. package/lib/logic/solidLogicSingleton.js.map +1 -1
  33. package/lib/profile/profileLogic.d.ts +3 -0
  34. package/lib/profile/profileLogic.d.ts.map +1 -0
  35. package/lib/profile/profileLogic.js +246 -0
  36. package/lib/profile/profileLogic.js.map +1 -0
  37. package/lib/typeIndex/typeIndexLogic.d.ts +2 -21
  38. package/lib/typeIndex/typeIndexLogic.d.ts.map +1 -1
  39. package/lib/typeIndex/typeIndexLogic.js +304 -296
  40. package/lib/typeIndex/typeIndexLogic.js.map +1 -1
  41. package/lib/types.d.ts +82 -1
  42. package/lib/types.d.ts.map +1 -1
  43. package/lib/util/containerLogic.d.ts +11 -0
  44. package/lib/util/containerLogic.d.ts.map +1 -0
  45. package/lib/{profile/ProfileLogic.js → util/containerLogic.js} +51 -44
  46. package/lib/util/containerLogic.js.map +1 -0
  47. package/lib/util/ns.d.ts +2 -0
  48. package/lib/util/ns.d.ts.map +1 -0
  49. package/lib/util/ns.js +34 -0
  50. package/lib/util/ns.js.map +1 -0
  51. package/lib/util/utilityLogic.d.ts +15 -0
  52. package/lib/util/utilityLogic.d.ts.map +1 -0
  53. package/lib/util/utilityLogic.js +274 -0
  54. package/lib/util/utilityLogic.js.map +1 -0
  55. package/lib/util/utils.d.ts +8 -0
  56. package/lib/util/utils.d.ts.map +1 -0
  57. package/lib/util/utils.js +48 -0
  58. package/lib/util/utils.js.map +1 -0
  59. package/package.json +3 -1
  60. package/src/acl/aclLogic.ts +136 -118
  61. package/src/authn/SolidAuthnLogic.ts +3 -2
  62. package/src/chat/chatLogic.ts +225 -0
  63. package/src/inbox/inboxLogic.ts +58 -0
  64. package/src/index.ts +11 -42
  65. package/src/logic/CustomError.ts +5 -1
  66. package/src/logic/solidLogic.ts +75 -0
  67. package/src/logic/solidLogicSingleton.ts +3 -3
  68. package/src/profile/profileLogic.ts +126 -0
  69. package/src/typeIndex/typeIndexLogic.ts +175 -182
  70. package/src/types.ts +83 -4
  71. package/src/util/containerLogic.ts +53 -0
  72. package/src/util/ns.ts +5 -0
  73. package/src/util/utilityLogic.ts +156 -0
  74. package/src/util/utils.ts +52 -0
  75. package/test/aclLogic.test.ts +13 -4
  76. package/test/chatLogic.test.ts +70 -71
  77. package/test/container.test.ts +57 -0
  78. package/test/helpers/dataSetup.ts +134 -0
  79. package/test/helpers/setup.ts +4 -0
  80. package/test/inboxLogic.test.ts +40 -38
  81. package/test/logic.test.ts +10 -9
  82. package/test/profileLogic.test.ts +246 -0
  83. package/test/typeIndexLogic.test.ts +487 -30
  84. package/test/utilityLogic.test.ts +172 -126
  85. package/test/utils.test.ts +32 -0
  86. package/lib/chat/ChatLogic.d.ts +0 -26
  87. package/lib/chat/ChatLogic.d.ts.map +0 -1
  88. package/lib/chat/ChatLogic.js.map +0 -1
  89. package/lib/chat/determineChatContainer.d.ts +0 -3
  90. package/lib/chat/determineChatContainer.d.ts.map +0 -1
  91. package/lib/chat/determineChatContainer.js +0 -12
  92. package/lib/chat/determineChatContainer.js.map +0 -1
  93. package/lib/discovery/discoveryLogic.d.ts +0 -37
  94. package/lib/discovery/discoveryLogic.d.ts.map +0 -1
  95. package/lib/discovery/discoveryLogic.js +0 -502
  96. package/lib/discovery/discoveryLogic.js.map +0 -1
  97. package/lib/inbox/InboxLogic.d.ts +0 -18
  98. package/lib/inbox/InboxLogic.d.ts.map +0 -1
  99. package/lib/inbox/InboxLogic.js.map +0 -1
  100. package/lib/logic/SolidLogic.d.ts +0 -45
  101. package/lib/logic/SolidLogic.d.ts.map +0 -1
  102. package/lib/logic/SolidLogic.js +0 -320
  103. package/lib/logic/SolidLogic.js.map +0 -1
  104. package/lib/profile/ProfileLogic.d.ts +0 -13
  105. package/lib/profile/ProfileLogic.d.ts.map +0 -1
  106. package/lib/profile/ProfileLogic.js.map +0 -1
  107. package/lib/util/UtilityLogic.d.ts +0 -27
  108. package/lib/util/UtilityLogic.d.ts.map +0 -1
  109. package/lib/util/UtilityLogic.js +0 -216
  110. package/lib/util/UtilityLogic.js.map +0 -1
  111. package/lib/util/uri.d.ts +0 -3
  112. package/lib/util/uri.d.ts.map +0 -1
  113. package/lib/util/uri.js +0 -9
  114. package/lib/util/uri.js.map +0 -1
  115. package/src/chat/ChatLogic.ts +0 -244
  116. package/src/chat/determineChatContainer.ts +0 -14
  117. package/src/discovery/discoveryLogic.ts +0 -269
  118. package/src/inbox/InboxLogic.ts +0 -66
  119. package/src/logic/SolidLogic.ts +0 -259
  120. package/src/profile/ProfileLogic.ts +0 -44
  121. package/src/util/UtilityLogic.ts +0 -144
  122. package/src/util/uri.ts +0 -5
  123. package/test/discoveryLogic.test.ts +0 -712
@@ -1,201 +1,194 @@
1
- import { NamedNode, st, sym } from "rdflib"
2
- import * as debug from '../util/debug'
3
- import solidNamespace from 'solid-namespace'
4
- import * as $rdf from 'rdflib'
5
- import { newThing } from "../util/uri"
6
- import { AuthenticationContext } from "../types"
7
- import { solidLogicSingleton } from "../logic/solidLogicSingleton"
8
- // import { ensureLoadedPreferences } from '../logic/logic'
9
- import { loadPreferences, loadProfile } from '../discovery/discoveryLogic'
10
- export const ns = solidNamespace($rdf)
11
-
12
- const store = solidLogicSingleton.store
13
-
14
- async function ensureLoadedPreferences (context:AuthenticationContext) {
15
- if (!context.me) throw new Error('@@ ensureLoadedPreferences: no user specified')
16
- context.publicProfile = await loadProfile(store, context.me)
17
- context.preferencesFile = await loadPreferences(store, context.me)
18
- return context
19
- }
1
+ import { NamedNode, st, sym } from 'rdflib'
2
+ import { ScopedApp, TypeIndexLogic, TypeIndexScope } from '../types'
3
+ import * as debug from "../util/debug"
4
+ import { ns as namespace } from '../util/ns'
5
+ import { newThing, uniqueNodes } from "../util/utils"
20
6
 
21
- /**
22
- * Resolves with the same context, outputting
23
- * output: index.public, index.private
24
- * @@ This is a very bizare function
25
- * @see https://github.com/solidos/solid/blob/main/proposals/data-discovery.md#discoverability
26
- */
27
- export async function loadIndex (
28
- context: AuthenticationContext,
29
- isPublic: boolean
30
- ): Promise<AuthenticationContext> {
31
- const indexes = await solidLogicSingleton.loadIndexes(
32
- context.me as NamedNode,
33
- (isPublic ? context.publicProfile || null : null),
34
- (isPublic ? null : context.preferencesFile || null),
35
- // async (err: Error) => widgets.complain(context, err.message)
36
- async (err: Error) => debug.error(err.message) as undefined
37
- )
38
- context.index = context.index || {}
39
- context.index.private = indexes.private.concat(context.index.private || []) // otherwise concat will wrongly add 'undefined' as a private index
40
- context.index.public = indexes.public.concat(context.index.public || []) // otherwise concat will wrongly add 'undefined' as a public index
41
- return context
42
- }
7
+ export function createTypeIndexLogic(store, authn, profileLogic, utilityLogic): TypeIndexLogic {
8
+ const ns = namespace
43
9
 
44
- export async function loadTypeIndexes (context: AuthenticationContext) {
45
- try {
46
- await loadPreferences(solidLogicSingleton.store, context.me as NamedNode)
47
- } catch (error) {
48
- debug.warn(error.message) as undefined
49
- }
50
- try {
51
- const indexes = await solidLogicSingleton.loadIndexes(
52
- context.me as NamedNode,
53
- context.publicProfile || null,
54
- context.preferencesFile || null,
55
- // async (err: Error) => widgets.complain(context, err.message)
56
- // async (err: Error) => debug.warn(err.message) as undefined
57
- )
58
- context.index = context.index || {}
59
- context.index.private = indexes.private || context.index.private
60
- context.index.public = indexes.public || context.index.public
61
- return context
62
- } catch (error) {
63
- async (error: Error) => debug.warn(error.message) as undefined
10
+ function getRegistrations(instance, theClass) {
11
+ return store
12
+ .each(undefined, ns.solid("instance"), instance)
13
+ .filter((r) => {
14
+ return store.holds(r, ns.solid("forClass"), theClass);
15
+ });
64
16
  }
65
- }
66
17
 
67
- /**
68
- * Resolves with the same context, outputting
69
- * @see https://github.com/solidos/solid/blob/main/proposals/data-discovery.md#discoverability
70
- */
71
- export async function ensureTypeIndexes (context: AuthenticationContext, agent?: NamedNode): Promise<AuthenticationContext> {
72
- if (!context.me) {
73
- throw new Error(`ensureTypeIndexes: @@ no user`)
74
- }
75
- await ensureOneTypeIndex(context, true, agent)
76
- await ensureOneTypeIndex(context, false, agent)
77
- return context
78
- }
18
+ async function loadTypeIndexesFor(user: NamedNode): Promise<Array<TypeIndexScope>> {
19
+ if (!user) throw new Error(`loadTypeIndexesFor: No user given`)
20
+ const profile = await profileLogic.loadProfile(user)
79
21
 
80
- /**
81
- * Load or create ONE type index
82
- * Find one or make one or fail
83
- * Many reasons for failing including script not having permission etc
84
- *
85
- * Adds its output to the context
86
- * @see https://github.com/solidos/solid/blob/main/proposals/data-discovery.md#discoverability
87
- */
88
- async function ensureOneTypeIndex (context: AuthenticationContext, isPublic: boolean, agent?: NamedNode): Promise<AuthenticationContext | void> {
89
- async function makeIndexIfNecessary (context, isPublic) {
90
- const relevant = isPublic ? context.publicProfile : context.preferencesFile
91
- if (!relevant) alert ('@@@@ relevent null')
92
- const visibility = isPublic ? 'public' : 'private'
93
-
94
- async function putIndex (newIndex) {
95
- try {
96
- await solidLogicSingleton.createEmptyRdfDoc(newIndex, 'Blank initial Type index')
97
- return context
98
- } catch (e) {
99
- const msg = `Error creating new index ${e}`
100
- // widgets.complain(context, msg)
101
- debug.warn(msg)
102
- }
103
- } // putIndex
22
+ const suggestion = suggestPublicTypeIndex(user)
23
+ let publicTypeIndex
24
+ try {
25
+ publicTypeIndex = await utilityLogic.followOrCreateLink(user, ns.solid('publicTypeIndex') as NamedNode, suggestion, profile)
26
+ } catch (err) {
27
+ const message = `User ${user} has no pointer in profile to publicTypeIndex file.`
28
+ debug.warn(message)
29
+ }
30
+ const publicScopes = publicTypeIndex ? [{ label: 'public', index: publicTypeIndex as NamedNode, agent: user }] : []
104
31
 
32
+ let preferencesFile
33
+ try {
34
+ preferencesFile = await profileLogic.silencedLoadPreferences(user)
35
+ } catch (err) {
36
+ preferencesFile = null
37
+ }
105
38
 
106
- context.index = context.index || {}
107
- context.index[visibility] = context.index[visibility] || []
108
- let newIndex
109
- if (context.index[visibility].length === 0) {
110
- if (!store.updater.editable(relevant)) {
111
- debug.log(`Not adding new type index as ${relevant} is not editable`)
112
- return
113
- }
114
- newIndex = sym(`${relevant.dir().uri + visibility}TypeIndex.ttl`)
115
- debug.log(`Linking to new fresh type index ${newIndex}`)
116
- if (!confirm(`OK to create a new empty index file at ${newIndex}, overwriting anything that is now there?`)) {
117
- throw new Error('cancelled by user')
118
- }
119
- debug.log(`Linking to new fresh type index ${newIndex}`)
120
- const addMe = [
121
- st(context.me, ns.solid(`${visibility}TypeIndex`), newIndex, relevant)
122
- ]
39
+ let privateScopes
40
+ if (preferencesFile) { // watch out - can be in either as spec was not clear. Legacy is profile.
41
+ // If there is a legacy one linked from the profile, use that.
42
+ // Otherwiae use or make one linked from Preferences
43
+ const suggestedPrivateTypeIndex = suggestPrivateTypeIndex(preferencesFile)
44
+ let privateTypeIndex
123
45
  try {
124
- await solidLogicSingleton.updatePromise([], addMe)
46
+ privateTypeIndex = store.any(user, ns.solid('privateTypeIndex'), undefined, profile) ||
47
+ await utilityLogic.followOrCreateLink(user, ns.solid('privateTypeIndex') as NamedNode, suggestedPrivateTypeIndex, preferencesFile);
125
48
  } catch (err) {
126
- const msg = `Error saving type index link saving back ${newIndex}: ${err}`
127
- //widgets.complain(context, msg)
128
- debug.warn(msg)
129
- return context
49
+ const message = `User ${user} has no pointer in preference file to privateTypeIndex file.`
50
+ debug.warn(message)
130
51
  }
131
-
132
- debug.log(`Creating new fresh type index file${newIndex}`)
133
- await putIndex(newIndex)
134
- context.index[visibility].push(newIndex) // @@ wait
52
+ privateScopes = privateTypeIndex ? [{ label: 'private', index: privateTypeIndex as NamedNode, agent: user }] : []
135
53
  } else {
136
- // officially exists
137
- const ixs = context.index[visibility]
138
- try {
139
- await solidLogicSingleton.load(ixs)
140
- } catch (err) {
141
- const msg = `ensureOneTypeIndex: loading indexes ${err}`
142
- debug.warn(msg)
143
- // widgets.complain(context, `ensureOneTypeIndex: loading indexes ${err}`)
144
- }
54
+ privateScopes = []
145
55
  }
146
- } // makeIndexIfNecessary
147
-
148
- const context2 = await ensureLoadedPreferences(context)
149
- if (!context2.publicProfile) throw new Error(`@@ type index: no publicProfile`)
150
- if (!context2.preferencesFile) throw new Error(`@@ type index: no preferencesFile for profile ${context2.publicProfile}`)
151
- const relevant = isPublic ? context2.publicProfile : context2.preferencesFile
152
-
153
- try {
154
- await loadIndex(context2, isPublic)
155
- const pp = isPublic ? 'public' : 'private'
156
- if (context2.index && context2.index[pp]&& context2.index[pp].length > 0) {
157
- debug.log(`ensureOneTypeIndex: Type index exists already ${context2.index[pp]}`)
158
- return context2
56
+ const scopes = publicScopes.concat(privateScopes)
57
+ if (scopes.length === 0) return scopes
58
+ const files = scopes.map(scope => scope.index)
59
+ try {
60
+ await store.fetcher.load(files)
61
+ } catch (err) {
62
+ debug.warn('Problems loading type index: ', err)
159
63
  }
160
- await makeIndexIfNecessary(context2, isPublic)
161
- } catch (error) {
162
- await makeIndexIfNecessary(context2, isPublic)
163
- // widgets.complain(context2, 'calling loadIndex:' + error)
64
+ return scopes
65
+ }
66
+
67
+ async function loadCommunityTypeIndexes(user: NamedNode): Promise<TypeIndexScope[][]> {
68
+ let preferencesFile
69
+ try {
70
+ preferencesFile = await profileLogic.silencedLoadPreferences(user)
71
+ } catch (err) {
72
+ const message = `User ${user} has no pointer in profile to preferences file.`
73
+ debug.warn(message)
74
+ }
75
+ if (preferencesFile) { // For now, pick up communities as simple links from the preferences file.
76
+ const communities = store.each(user, ns.solid('community'), undefined, preferencesFile as NamedNode).concat(
77
+ store.each(user, ns.solid('community'), undefined, user.doc() as NamedNode)
78
+ )
79
+ let result = []
80
+ for (const org of communities) {
81
+ result = result.concat(await loadTypeIndexesFor(org as NamedNode) as any)
82
+ }
83
+ return result
84
+ }
85
+ return [] // No communities
164
86
  }
165
- }
166
87
 
167
- /**
168
- * Register a new app in a type index
169
- * used in chat in bookmark.js (solid-ui)
170
- */
171
- export async function registerInTypeIndex (
172
- context: AuthenticationContext,
173
- instance: NamedNode,
174
- theClass: NamedNode,
175
- isPublic: boolean,
176
- agent?: NamedNode // Defaults to current user
177
- ): Promise<AuthenticationContext> {
178
- await ensureOneTypeIndex(context, isPublic, agent)
179
- if (!context.index) {
180
- throw new Error('registerInTypeIndex: No type index found')
88
+ async function loadAllTypeIndexes(user: NamedNode) {
89
+ return (await loadTypeIndexesFor(user)).concat((await loadCommunityTypeIndexes(user)).flat())
181
90
  }
182
- const indexes = isPublic ? context.index.public : context.index.private
183
- if (!indexes.length) {
184
- throw new Error('registerInTypeIndex: What no type index?')
91
+
92
+ async function getScopedAppInstances(klass: NamedNode, user: NamedNode): Promise<ScopedApp[]> {
93
+ const scopes = await loadAllTypeIndexes(user)
94
+ let scopedApps = []
95
+ for (const scope of scopes) {
96
+ const scopedApps0 = await getScopedAppsFromIndex(scope, klass) as any
97
+ scopedApps = scopedApps.concat(scopedApps0)
98
+ }
99
+ return scopedApps
100
+ }
101
+
102
+ // This is the function signature which used to be in solid-ui/logic
103
+ // Recommended to use getScopedAppInstances instead as it provides more information.
104
+ //
105
+ async function getAppInstances(klass: NamedNode): Promise<NamedNode[]> {
106
+ const user = authn.currentUser()
107
+ if (!user) throw new Error('getAppInstances: Must be logged in to find apps.')
108
+ const scopedAppInstances = await getScopedAppInstances(klass, user)
109
+ return scopedAppInstances.map(scoped => scoped.instance)
110
+ }
111
+
112
+ function suggestPublicTypeIndex(me: NamedNode) {
113
+ return sym(me.doc().dir()?.uri + 'publicTypeIndex.ttl')
114
+ }
115
+ // Note this one is based off the pref file not the profile
116
+
117
+ function suggestPrivateTypeIndex(preferencesFile: NamedNode) {
118
+ return sym(preferencesFile.doc().dir()?.uri + 'privateTypeIndex.ttl')
119
+ }
120
+
121
+ /*
122
+ * Register a new app in a type index
123
+ * used in chat in bookmark.js (solid-ui)
124
+ * Returns the registration object if successful else null
125
+ */
126
+ async function registerInTypeIndex(
127
+ instance: NamedNode,
128
+ index: NamedNode,
129
+ theClass: NamedNode,
130
+ // agent: NamedNode
131
+ ): Promise<NamedNode | null> {
132
+ const registration = newThing(index)
133
+ const ins = [
134
+ // See https://github.com/solid/solid/blob/main/proposals/data-discovery.md
135
+ st(registration, ns.rdf('type'), ns.solid('TypeRegistration'), index),
136
+ st(registration, ns.solid('forClass'), theClass, index),
137
+ st(registration, ns.solid('instance'), instance, index)
138
+ ]
139
+ try {
140
+ await store.updater.update([], ins)
141
+ } catch (err) {
142
+ const msg = `Unable to register ${instance} in index ${index}: ${err}`
143
+ console.warn(msg)
144
+ return null
145
+ }
146
+ return registration
147
+ }
148
+
149
+ async function deleteTypeIndexRegistration(item) {
150
+ const reg = store.the(null, ns.solid('instance'), item.instance, item.scope.index) as NamedNode
151
+ if (!reg) throw new Error(`deleteTypeIndexRegistration: No registration found for ${item.instance}`)
152
+ const statements = store.statementsMatching(reg, null, null, item.scope.index)
153
+ await store.updater.update(statements, [])
154
+ }
155
+
156
+ async function getScopedAppsFromIndex(scope: TypeIndexScope, theClass: NamedNode | null): Promise<ScopedApp[]> {
157
+ const index = scope.index
158
+ const registrations = store.statementsMatching(null, ns.solid('instance'), null, index)
159
+ .concat(store.statementsMatching(null, ns.solid('instanceContainer'), null, index))
160
+ .map(st => st.subject)
161
+ const relevant = theClass ? registrations.filter(reg => store.any(reg, ns.solid('forClass'), null, index)?.sameTerm(theClass))
162
+ : registrations
163
+ const directInstances = relevant.map(reg => store.each(reg, ns.solid('instance'), null, index).map(one => sym(one.value))).flat()
164
+ let instances = uniqueNodes(directInstances)
165
+
166
+ const instanceContainers = relevant.map(
167
+ reg => store.each(reg, ns.solid('instanceContainer'), null, index).map(one => sym(one.value))).flat()
168
+
169
+ // instanceContainers may be deprocatable if no one has used them
170
+ const containers = uniqueNodes(instanceContainers)
171
+ if (containers.length > 0) { console.log('@@ getScopedAppsFromIndex containers ', containers) }
172
+ for (let i = 0; i < containers.length; i++) {
173
+ const cont = containers[i]
174
+ await store.fetcher.load(cont)
175
+ const contents = store.each(cont, ns.ldp('contains'), null, cont).map(one => sym(one.value))
176
+ instances = instances.concat(contents)
177
+ }
178
+ return instances.map(instance => { return { instance, scope } })
185
179
  }
186
- const index = indexes[0]
187
- const registration = newThing(index)
188
- const ins = [
189
- // See https://github.com/solidos/solid/blob/main/proposals/data-discovery.md
190
- st(registration, ns.rdf('type'), ns.solid('TypeRegistration'), index),
191
- st(registration, ns.solid('forClass'), theClass, index),
192
- st(registration, ns.solid('instance'), instance, index)
193
- ]
194
- try {
195
- await solidLogicSingleton.updatePromise([], ins)
196
- } catch (e) {
197
- debug.log(e)
198
- alert(e)
180
+
181
+ return {
182
+ registerInTypeIndex,
183
+ getRegistrations,
184
+ loadTypeIndexesFor,
185
+ loadCommunityTypeIndexes,
186
+ loadAllTypeIndexes,
187
+ getScopedAppInstances,
188
+ getAppInstances,
189
+ suggestPublicTypeIndex,
190
+ suggestPrivateTypeIndex,
191
+ deleteTypeIndexRegistration,
192
+ getScopedAppsFromIndex
199
193
  }
200
- return context
201
194
  }
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Session } from "@inrupt/solid-client-authn-browser"
2
- import { NamedNode } from "rdflib"
2
+ import { LiveStore, NamedNode, Statement } from "rdflib"
3
3
 
4
4
  export type AppDetails = {
5
5
  noun: string
@@ -32,12 +32,91 @@ export interface SolidNamespace {
32
32
  [key: string]: (term: string) => NamedNode
33
33
  }
34
34
 
35
- interface NewPaneOptions {
35
+ export type TypeIndexScope = { label: string, index: NamedNode, agent: NamedNode }
36
+ export type ScopedApp = { instance: NamedNode, scope: TypeIndexScope }
37
+
38
+ export interface NewPaneOptions {
36
39
  me?: NamedNode;
37
40
  newInstance?: NamedNode;
38
41
  newBase: string;
39
42
  }
40
43
 
41
- interface CreatedPaneOptions {
44
+ export interface CreatedPaneOptions {
42
45
  newInstance: NamedNode;
43
- }
46
+ }
47
+
48
+ export interface ChatLogic {
49
+ setAcl: (chatContainer: NamedNode, me: NamedNode, invitee: NamedNode) => Promise<void>,
50
+ addToPrivateTypeIndex: (chatThing, me) => void | Promise<void>,
51
+ findChat: (invitee: NamedNode) => Promise<Chat>,
52
+ createChatThing: (chatContainer: NamedNode, me: NamedNode) => Promise<NamedNode>,
53
+ mintNew: (newPaneOptions: NewPaneOptions) => Promise<CreatedPaneOptions>,
54
+ getChat: (invitee: NamedNode, boolean) => Promise<NamedNode | null>,
55
+ sendInvite: (invitee: NamedNode, chatThing: NamedNode) => void
56
+ }
57
+
58
+ export interface Chat {
59
+ me: NamedNode,
60
+ chatContainer: NamedNode,
61
+ exists: boolean
62
+ }
63
+
64
+ export interface ProfileLogic {
65
+ silencedLoadPreferences: (user: NamedNode) => Promise<NamedNode | undefined>,
66
+ loadPreferences: (user: NamedNode) => Promise<NamedNode>,
67
+ loadProfile: (user: NamedNode) => Promise<NamedNode>,
68
+ loadMe: () => Promise<NamedNode>,
69
+ getPodRoot: (user: NamedNode) => NamedNode,
70
+ getMainInbox: (user: NamedNode) => Promise<NamedNode>,
71
+ findStorage: (me: NamedNode) => Node | null
72
+ }
73
+
74
+ export interface AclLogic {
75
+ findAclDocUrl: (url: NamedNode) => Promise<any>,
76
+ setACLUserPublic: (docURI: string, me: NamedNode,
77
+ options: {
78
+ defaultForNew?: boolean,
79
+ public?: []
80
+ }
81
+ ) => Promise<NamedNode>,
82
+ genACLText: (docURI: string, me: NamedNode, aclURI: string,
83
+ options: {
84
+ defaultForNew?: boolean,
85
+ public?: []
86
+ }
87
+ ) => string | undefined
88
+ }
89
+
90
+ export interface InboxLogic {
91
+ createInboxFor: (peerWebId: string, nick: string) => Promise<string>,
92
+ getNewMessages: (user?: NamedNode) => Promise<NamedNode[]>,
93
+ markAsRead: (url: string, date: Date) => void
94
+ }
95
+
96
+ export interface TypeIndexLogic {
97
+ getRegistrations: (instance, theClass) => Node[],
98
+ loadTypeIndexesFor: (user: NamedNode) => Promise<Array<TypeIndexScope>>,
99
+ loadCommunityTypeIndexes: (user: NamedNode) => Promise<TypeIndexScope[][]>,
100
+ loadAllTypeIndexes: (user: NamedNode) => Promise<Array<TypeIndexScope>>,
101
+ getScopedAppInstances: (klass: NamedNode, user: NamedNode) => Promise<ScopedApp[]>,
102
+ getAppInstances: (klass: NamedNode) => Promise<NamedNode[]>,
103
+ suggestPublicTypeIndex: (me: NamedNode) => NamedNode,
104
+ suggestPrivateTypeIndex: (preferencesFile: NamedNode) => NamedNode,
105
+ registerInTypeIndex: (instance: NamedNode, index: NamedNode, theClass: NamedNode) => Promise<NamedNode | null>,
106
+ deleteTypeIndexRegistration: (item: any) => Promise<void>
107
+ getScopedAppsFromIndex: (scope: TypeIndexScope, theClass: NamedNode | null) => Promise<ScopedApp[]>
108
+ }
109
+
110
+ export interface SolidLogic {
111
+ store: LiveStore,
112
+ authn: AuthnLogic,
113
+ acl: AclLogic,
114
+ profile: ProfileLogic,
115
+ inbox: InboxLogic,
116
+ typeIndex: TypeIndexLogic,
117
+ chat: ChatLogic,
118
+ load: (doc: NamedNode | NamedNode[] | string) => void,
119
+ updatePromise: (del: Array<Statement>, ins: Array<Statement>) => Promise<void>,
120
+ clearStore: () => void
121
+ }
122
+
@@ -0,0 +1,53 @@
1
+ import { NamedNode, Statement, sym } from "rdflib";
2
+
3
+ /**
4
+ * Container-related class
5
+ */
6
+ export function createContainerLogic(store) {
7
+
8
+ function getContainerElements(containerNode: NamedNode): NamedNode[] {
9
+ return store
10
+ .statementsMatching(
11
+ containerNode,
12
+ sym("http://www.w3.org/ns/ldp#contains"),
13
+ undefined
14
+ )
15
+ .map((st: Statement) => st.object as NamedNode);
16
+ }
17
+
18
+ function isContainer(url: NamedNode) {
19
+ const nodeToString = url.value;
20
+ return nodeToString.charAt(nodeToString.length - 1) === "/";
21
+ }
22
+
23
+ async function createContainer(url: string) {
24
+ const stringToNode = sym(url);
25
+ if (!isContainer(stringToNode)) {
26
+ throw new Error(`Not a container URL ${url}`);
27
+ }
28
+ // Copied from https://github.com/solidos/solid-crud-tests/blob/v3.1.0/test/surface/create-container.test.ts#L56-L64
29
+ const result = await store.fetcher._fetch(url, {
30
+ method: "PUT",
31
+ headers: {
32
+ "Content-Type": "text/turtle",
33
+ "If-None-Match": "*",
34
+ Link: '<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"', // See https://github.com/solidos/node-solid-server/issues/1465
35
+ },
36
+ body: " ", // work around https://github.com/michielbdejong/community-server/issues/4#issuecomment-776222863
37
+ });
38
+ if (result.status.toString()[0] !== '2') {
39
+ throw new Error(`Not OK: got ${result.status} response while creating container at ${url}`);
40
+ }
41
+ }
42
+
43
+ async function getContainerMembers(containerUrl: NamedNode): Promise<NamedNode[]> {
44
+ await store.fetcher.load(containerUrl);
45
+ return getContainerElements(containerUrl);
46
+ }
47
+ return {
48
+ isContainer,
49
+ createContainer,
50
+ getContainerElements,
51
+ getContainerMembers
52
+ }
53
+ }
package/src/util/ns.ts ADDED
@@ -0,0 +1,5 @@
1
+ // Namespaces we commonly use and have common prefixes for around Solid
2
+ import solidNamespace from 'solid-namespace' // Delegate to this which takes RDFlib as param.
3
+ import * as $rdf from 'rdflib'
4
+
5
+ export const ns = solidNamespace($rdf)