@openstax/ts-utils 1.2.4 → 1.2.5

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.
@@ -19,12 +19,21 @@ export declare const resolveActivityAttemptInfo: (statements: XapiStatement[], a
19
19
  parentActivityAttempt?: string | undefined;
20
20
  currentPreference?: "latest" | "oldest" | undefined;
21
21
  } | undefined) => ActivityState;
22
- export declare const loadStatementsForActivityAndFirstChildren: (gateway: LrsGateway, activityIRI: string, attempt?: string | undefined) => Promise<XapiStatement[]>;
23
- export declare const loadStatementsForAttempt: (gateway: LrsGateway, attempt: string) => Promise<XapiStatement[]>;
24
- export declare const loadStatementsForActivity: (gateway: LrsGateway, activityIRI: string, attempt?: string | undefined) => Promise<XapiStatement[]>;
22
+ export declare const loadStatementsForActivityAndFirstChildren: (gateway: LrsGateway, activityIRI: string, options?: {
23
+ attempt?: string | undefined;
24
+ ensureSync?: boolean | undefined;
25
+ } | undefined) => Promise<XapiStatement[]>;
26
+ export declare const loadStatementsForAttempt: (gateway: LrsGateway, attempt: string, options?: {
27
+ ensureSync?: boolean | undefined;
28
+ } | undefined) => Promise<XapiStatement[]>;
29
+ export declare const loadStatementsForActivity: (gateway: LrsGateway, activityIRI: string, options?: {
30
+ attempt?: string | undefined;
31
+ ensureSync?: boolean | undefined;
32
+ } | undefined) => Promise<XapiStatement[]>;
25
33
  export declare const loadActivityAttemptInfo: (gateway: LrsGateway, activityIRI: string, options?: {
26
34
  currentAttempt?: string | undefined;
27
35
  parentActivityAttempt?: string | undefined;
36
+ ensureSync?: boolean | undefined;
28
37
  } | undefined) => Promise<ActivityState>;
29
38
  export declare const createStatement: (verb: XapiStatement['verb'], activity: {
30
39
  iri: string;
@@ -78,32 +78,39 @@ export const resolveActivityAttemptInfo = (statements, activityIRI, options) =>
78
78
  * statements would then have to be fetched using `loadStatementsForActivity(gateway, childActivityIRI, childAttemptStatementID)`. this
79
79
  * is because child activities could have multiple attempts under one attempt on the parent activity.
80
80
  */
81
- export const loadStatementsForActivityAndFirstChildren = (gateway, activityIRI, attempt) => {
81
+ export const loadStatementsForActivityAndFirstChildren = (gateway, activityIRI, options) => {
82
+ const { attempt, ...partialOptions } = options ? options : { attempt: undefined };
83
+ const getOptions = attempt ? { registration: attempt, ...partialOptions } : partialOptions;
82
84
  return gateway.getAllXapiStatements({
83
85
  activity: activityIRI,
84
86
  related_activities: true,
85
- ...(attempt ? { registration: attempt } : {})
87
+ ...getOptions,
86
88
  });
87
89
  };
88
90
  /*
89
91
  * loads all statements (for this actor) that have the given parent attempt (registration)
90
92
  */
91
- export const loadStatementsForAttempt = (gateway, attempt) => {
93
+ export const loadStatementsForAttempt = (gateway, attempt, options) => {
92
94
  return gateway.getAllXapiStatements({
93
- registration: attempt
95
+ registration: attempt,
96
+ ...(options ? options : {})
94
97
  });
95
98
  };
96
99
  /*
97
100
  * loads all statements (for this actor) that have the given activityIRI as the object.id
98
101
  */
99
- export const loadStatementsForActivity = (gateway, activityIRI, attempt) => {
102
+ export const loadStatementsForActivity = (gateway, activityIRI, options) => {
103
+ const { attempt, ...partialOptions } = options ? options : { attempt: undefined };
104
+ const getOptions = attempt ? { registration: attempt, ...partialOptions } : partialOptions;
100
105
  return gateway.getAllXapiStatements({
101
106
  activity: activityIRI,
102
- ...(attempt ? { registration: attempt } : {})
107
+ ...getOptions,
103
108
  });
104
109
  };
105
110
  export const loadActivityAttemptInfo = async (gateway, activityIRI, options) => {
106
- return resolveActivityAttemptInfo(await loadStatementsForActivity(gateway, activityIRI, options === null || options === void 0 ? void 0 : options.parentActivityAttempt), activityIRI, options);
111
+ const { parentActivityAttempt, ...partialOptions } = options ? options : { parentActivityAttempt: undefined };
112
+ const loadOptions = parentActivityAttempt ? { attempt: parentActivityAttempt } : partialOptions;
113
+ return resolveActivityAttemptInfo(await loadStatementsForActivity(gateway, activityIRI, loadOptions), activityIRI, options);
107
114
  };
108
115
  export const createStatement = (verb, activity, attempt, parentActivityIRI) => {
109
116
  return {
@@ -83,11 +83,12 @@ export declare const lrsGateway: <C extends string = "lrs">(initializer: Initial
83
83
  putXapiStatements: (statements: Array<Pick<XapiStatement, 'object' | 'verb' | 'context' | 'result'> & {
84
84
  id?: string;
85
85
  }>) => Promise<EagerXapiStatement[]>;
86
- getXapiStatements: ({ user, anyUser, ...options }: {
86
+ getXapiStatements: (params: {
87
87
  verb?: string | undefined;
88
88
  activity?: string | undefined;
89
89
  registration?: string | undefined;
90
90
  related_activities?: boolean | undefined;
91
+ ensureSync?: boolean | undefined;
91
92
  user?: string | undefined;
92
93
  anyUser?: boolean | undefined;
93
94
  }) => Promise<{
@@ -98,11 +99,12 @@ export declare const lrsGateway: <C extends string = "lrs">(initializer: Initial
98
99
  more: string;
99
100
  statements: XapiStatement[];
100
101
  }>;
101
- getAllXapiStatements: (args_0: {
102
+ getAllXapiStatements: (params: {
102
103
  verb?: string | undefined;
103
104
  activity?: string | undefined;
104
105
  registration?: string | undefined;
105
106
  related_activities?: boolean | undefined;
107
+ ensureSync?: boolean | undefined;
106
108
  user?: string | undefined;
107
109
  anyUser?: boolean | undefined;
108
110
  }) => Promise<XapiStatement[]>;
@@ -1,6 +1,6 @@
1
1
  import formatISO from 'date-fns/formatISO';
2
2
  import * as queryString from 'query-string';
3
- import { once } from '../..';
3
+ import { once, retryWithDelay } from '../..';
4
4
  import { assertDefined } from '../../assertions';
5
5
  import { resolveConfigValue } from '../../config';
6
6
  import { UnauthorizedError } from '../../errors';
@@ -59,7 +59,7 @@ ${await response.text()}`);
59
59
  'X-Experience-API-Version': '1.0.0',
60
60
  },
61
61
  }));
62
- const getXapiStatements = async ({ user, anyUser, ...options }) => formatGetXapiStatementsResponse(initializer.fetch((await lrsHost()).replace(/\/+$/, '') + '/data/xAPI/statements?' + queryString.stringify({
62
+ const fetchXapiStatements = async ({ user, anyUser, ...options }) => initializer.fetch((await lrsHost()).replace(/\/+$/, '') + '/data/xAPI/statements?' + queryString.stringify({
63
63
  ...options,
64
64
  ...(anyUser === true ? {} : {
65
65
  agent: JSON.stringify({
@@ -75,8 +75,25 @@ ${await response.text()}`);
75
75
  Authorization: await lrsAuthorization(),
76
76
  'X-Experience-API-Version': '1.0.0',
77
77
  },
78
- }));
79
- const getAllXapiStatements = async (...args) => {
78
+ });
79
+ const getXapiStatements = async (params) => {
80
+ if (params.ensureSync) {
81
+ const date = new Date();
82
+ return retryWithDelay(async () => {
83
+ const responsePromise = fetchXapiStatements(params);
84
+ const response = await responsePromise;
85
+ const consistentThrough = response.headers.get('X-Experience-API-Consistent-Through');
86
+ if (!consistentThrough || new Date(consistentThrough) < date) {
87
+ throw new Error(`xAPI consistent through ${consistentThrough}; not in sync with current date ${date}.`);
88
+ }
89
+ return formatGetXapiStatementsResponse(responsePromise);
90
+ });
91
+ }
92
+ else {
93
+ return formatGetXapiStatementsResponse(fetchXapiStatements(params));
94
+ }
95
+ };
96
+ const getAllXapiStatements = async (params) => {
80
97
  const loadRemaining = async (result) => {
81
98
  if (!result.more) {
82
99
  return result.statements;
@@ -84,7 +101,7 @@ ${await response.text()}`);
84
101
  const { more, statements } = await getMoreXapiStatements(result.more);
85
102
  return loadRemaining({ more, statements: [...result.statements, ...statements] });
86
103
  };
87
- return loadRemaining(await getXapiStatements(...args));
104
+ return loadRemaining(await getXapiStatements(params));
88
105
  };
89
106
  return {
90
107
  putXapiStatements,