зеркало из
1
0
Форкнуть 0

Create @azure/communication-react meta package (#211)

This commit is contained in:
James Burnside 2021-05-05 13:28:58 -07:00 коммит произвёл GitHub
Родитель 427648c23c
Коммит 6dd6aeb425
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
24 изменённых файлов: 854 добавлений и 1870 удалений

20
.github/workflows/nightly-ci.yml поставляемый
Просмотреть файл

@ -81,24 +81,12 @@ jobs:
run: node common/config/node_modules/beachball/bin/beachball canary --canary-name alpha+${{ steps.datetime.outputs.datetime }} --tag dev --no-publish
# Build packages
- name: Build react-components package
run: rush build -t react-components
- name: Build react-composites package
run: rush build -t react-composites
- name: Build @azure/acs-calling-declarative package
run: rush build -t @azure/acs-calling-declarative
- name: Build @azure/acs-chat-declarative package
run: rush build -t @azure/acs-chat-declarative
- name: Build @azure/communication-react package
run: rush build -t @azure/communication-react
# Test Packages
- name: Test react-components package
run: rush test -o react-components
- name: Test react-components package
run: rush test -o react-composites
- name: Test @azure/acs-calling-declarative package
run: rush test -o @azure/acs-calling-declarative
- name: Test @azure/acs-chat-declarative package
run: rush test -o @azure/acs-chat-declarative
- name: Test @azure/communication-react package
run: rush test -t @azure/communication-react
# Publish package
- name: Publish alpha packages

4
.github/workflows/npm-release-publish.yml поставляемый
Просмотреть файл

@ -45,10 +45,6 @@ jobs:
- name: Build Packages and Samples
run: rush build
- name: Build Storybook
run: rushx build:storybook
working-directory: ./packages/react-components
# Run tests
- name: Run Tests
run: rush test

Просмотреть файл

@ -33,6 +33,7 @@ jobs:
rush build -t "@azure/acs-chat-selector"
rush build -t "@azure/acs-calling-declarative"
rush build -t "@azure/acs-calling-selector"
rush build -t "@azure/communication-react"
- name: Package @react-components
run: npm pack
@ -58,6 +59,10 @@ jobs:
run: npm pack
working-directory: ./packages/acs-calling-selector/
- name: Package @azure/communication-react
run: npm pack
working-directory: ./packages/communication-react/
- name: Compile private preview zip
run: 7z a private-preview.zip ./packages/**/private-preview/*

5
.gitignore поставляемый
Просмотреть файл

@ -83,10 +83,13 @@ common/autoinstallers/*/.npmrc
# Test reporter results
junit.xml
# tsdoc
tsdoc-metadata.json
# Common build folders
dist/
build/
temp/
docGen/
private-preview/
private-preview.zip
private-preview.zip

Просмотреть файл

@ -1,7 +0,0 @@
{
"type": "prerelease",
"comment": "Add userId to callClientDeclaratify to add userId to Declarative state",
"packageName": "@azure/communication-ui",
"email": "allenhwang@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Remove dependency on chat-selector",
"packageName": "react-components",
"email": "mail@jamesburnside.com",
"dependentChangeType": "patch"
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,30 @@
{
"compilerOptions": {
"target": "es6",
"module": "esnext",
"jsx": "react",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"strict": true,
"noImplicitAny": false, // disable for now for storybook
"strictFunctionTypes": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleResolution": "node"
}
}

Просмотреть файл

@ -0,0 +1,5 @@
docs/
public/
dist/
node_modules/
scripts/

Просмотреть файл

@ -0,0 +1,55 @@
// © Microsoft Corporation. All rights reserved.
module.exports = {
env: {
browser: true,
node: true,
es6: true
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'header'],
parserOptions: {
ecmaFeatures: {
jsx: true
},
ecmaVersion: 2020,
sourceType: 'module'
},
rules: {
'@typescript-eslint/explicit-function-return-type': [
'warn',
{
allowExpressions: true,
allowTypedFunctionExpressions: true
}
],
'@typescript-eslint/no-explicit-any': 'off',
eqeqeq: 'warn',
'header/header': ['error', 'line', ' © Microsoft Corporation. All rights reserved.'],
'react/display-name': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { varsIgnorePattern: '^_' }]
},
root: true,
settings: {
react: {
version: 'detect'
}
},
overrides: [
{
files: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx', '**/mocks/*'],
rules: {
'@typescript-eslint/ban-ts-comment': 'off'
},
env: {
jest: true
}
}
]
};

Просмотреть файл

@ -0,0 +1,10 @@
# Disallow everything by default so new files aren't accidently included:
*
# Allow dist folder, this is the folder that should be packed and published:
!dist/**/*
# Exceptions in the dist folder that should still be disallowed:
dist/**/mocks/
**/*.test.*
**/*.spec.*

Просмотреть файл

@ -0,0 +1,3 @@
# @Azure/communication-react
Todo: _documentation to follow_

Просмотреть файл

@ -0,0 +1,4 @@
{
"extends": "../../common/config/api-extractor/api-extractor.json",
"mainEntryPointFilePath": "<projectFolder>/dist/dist-esm/communication-react/src/index.d.ts"
}

Просмотреть файл

@ -0,0 +1,99 @@
{
"name": "@azure/communication-react",
"version": "1.0.0-beta",
"description": "React library for building modern communication user experiences utilizing Azure Communication Services",
"keywords": [
"Communication",
"Chat",
"Call",
"VOIP",
"Video",
"Video conferencing",
"Teams"
],
"homepage": "https://azure.github.io/communication-ui-sdk/",
"license": "MIT",
"repository": {
"type" : "git",
"url" : "https://github.com/Azure/communication-ui-sdk.git"
},
"bugs": {
"url": "https://github.com/Azure/communication-ui-sdk/issues/new/choose"
},
"types": "dist/communication-react.d.ts",
"dependencies": {
"@fluentui/react": "^7.117.1",
"@fluentui/react-icons": "^0.3.9",
"@fluentui/react-icons-northstar": "^0.51.2",
"@fluentui/react-northstar": "^0.51.2",
"@fluentui/react-theme-provider": "^0.18.0",
"react-aria-live": "^2.0.5",
"react-linkify": "^1.0.0-alpha"
},
"peerDependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"main": "./dist/dist-cjs/communication-react/index.js",
"module": "./dist/dist-esm/communication-react/src/index.js",
"scripts": {
"build": "rushx build:esm && rushx build:cjs && api-extractor run --local",
"build:cjs": "rollup -c --silent",
"build:esm": "tsc",
"build:watch": "",
"test": "",
"test:coverage": "",
"api-extractor": "tsc && api-extractor run --local",
"generate-doc": "api-documenter markdown -i temp -o docGen",
"prettier": "prettier --write --config ../../.prettierrc \"**/*.js\" \"**/*.ts\"",
"prettier:check": "prettier --check --config ../../.prettierrc \"**/*.js\" \"**/*.ts\"",
"lint": "eslint \"*/**/*.{ts,tsx}\"",
"lint:fix": "npm run lint -- --fix",
"lint:quiet": "npm run lint -- --quiet"
},
"devDependencies": {
"@microsoft/api-documenter": "~7.12.11",
"@microsoft/api-extractor": "~7.13.2",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react-hooks": "^3.4.2",
"@types/jest": "^26.0.20",
"@types/json-stringify-safe": "^5.0.0",
"@types/node": "^14.14.10",
"@types/react-aria-live": "^2.0.0",
"@types/react-dom": "^16.9.8",
"@types/react-linkify": "^1.0.0",
"@types/react": "^16.9.49",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^4.12.0",
"@typescript-eslint/parser": "^4.12.0",
"ajv": "^6.9.1",
"copyfiles": "^2.4.1",
"eslint-config-prettier": "^6.12.0",
"eslint-plugin-header": "^3.1.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react-hooks": "^4.1.2",
"eslint-plugin-react": "^7.18.3",
"eslint": "^7.7.0",
"json-stringify-safe": "^5.0.1",
"node-forge": "0.10.0",
"prettier": "2.0.5",
"pretty-quick": "^3.1.0",
"react-dom": "^16.13.1",
"react-is": "~17.0.1",
"react": "^16.13.1",
"react-components": "1.0.0-beta",
"regenerator-runtime": "^0.13.7",
"rollup": "~2.42.4",
"source-map-explorer": "^2.5.0",
"styled-components": "~5.2.1",
"ts-jest": "^26.4.4",
"ts-node": "^9.1.1",
"typescript": "4.1.5",
"uuid": "^8.1.0"
},
"beachball": {
"shouldPublish": false
}
}

Просмотреть файл

@ -0,0 +1,405 @@
## API Report File for "@azure/communication-react"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { ComponentSlotStyle } from '@fluentui/react-northstar';
import { IButtonProps } from '@fluentui/react';
import { IContextualMenuItem } from '@fluentui/react';
import { IStyle } from '@fluentui/react';
import { PartialTheme } from '@fluentui/react-theme-provider';
import { PersonaPresence } from '@fluentui/react';
import { default as React_2 } from 'react';
import { SizeValue } from '@fluentui/react-northstar';
import { Theme } from '@fluentui/react-theme-provider';
// @public
export const answerButtonProps: IButtonProps;
// @public (undocumented)
export interface BaseCustomStylesProps {
root?: IStyle;
}
// @public
export const CameraButton: (props: CameraButtonProps) => JSX.Element;
// @public
export interface CameraButtonProps extends IButtonProps {
showLabel?: boolean;
}
// @public (undocumented)
export type ChatMessage = Message<'chat'>;
// @public (undocumented)
export type ChatMessagePayload = {
messageId?: string;
content?: string;
createdOn?: Date;
senderId?: string;
senderDisplayName?: string;
status?: MessageStatus;
attached?: MessageAttachedStatus | boolean;
mine?: boolean;
clientMessageId?: string;
};
// @public
export enum CommunicationUiErrorSeverity {
// (undocumented)
ERROR = "Error",
// (undocumented)
IGNORE = "Ignore",
// (undocumented)
INFO = "Info",
// (undocumented)
WARNING = "Warning"
}
// @public
export const ControlBar: (props: ControlBarProps) => JSX.Element;
// @public (undocumented)
export type ControlBarLayoutType = 'horizontal' | 'vertical' | 'dockedTop' | 'dockedBottom' | 'dockedLeft' | 'dockedRight' | 'floatingTop' | 'floatingBottom' | 'floatingLeft' | 'floatingRight';
// @public
export interface ControlBarProps {
children?: React_2.ReactNode;
layout?: ControlBarLayoutType;
styles?: BaseCustomStylesProps;
}
// @public (undocumented)
export type CustomMessage = Message<'custom'>;
// @public (undocumented)
export type CustomMessagePayload = {
messageId: string;
content?: string;
};
// @public (undocumented)
export type DefaultMessageRendererType = (props: MessageProps) => JSX.Element;
// @public
export const defaultThemes: ThemeCollection;
// @public
export const EndCallButton: (props: EndCallButtonProps) => JSX.Element;
// @public
export interface EndCallButtonProps extends IButtonProps {
showLabel?: boolean;
}
// @public
export const ErrorBar: (props: ErrorBarProps) => JSX.Element | null;
// @public
export type ErrorBarProps = {
message?: string;
severity?: CommunicationUiErrorSeverity;
onClose?: () => void;
styles?: BaseCustomStylesProps;
};
// @public
export const FluentThemeProvider: (props: FluentThemeProviderProps) => JSX.Element;
// @public
export interface FluentThemeProviderProps {
children: React_2.ReactNode;
fluentTheme?: PartialTheme | Theme;
}
// @public (undocumented)
export const GridLayout: (props: GridLayoutProps) => JSX.Element;
// @public (undocumented)
export interface GridLayoutProps {
// (undocumented)
children: React_2.ReactNode;
// (undocumented)
layout?: GridLayoutType;
styles?: BaseCustomStylesProps;
}
// @public (undocumented)
export type GridLayoutType = 'standard';
// @public (undocumented)
export interface JumpToNewMessageButtonProps {
// (undocumented)
onClick: () => void;
}
// @public
export const labeledAnswerButtonProps: IButtonProps;
// @public
export const labeledRecordButtonProps: IButtonProps;
// @public (undocumented)
export type Message<T extends MessageTypes> = {
type: T;
payload: T extends 'chat' ? ChatMessagePayload : T extends 'system' ? SystemMessagePayload : CustomMessagePayload;
};
// @public (undocumented)
export enum MessageAttachedStatus {
// (undocumented)
BOTTOM = "bottom",
// (undocumented)
TOP = "top"
}
// @public
export type MessageProps = {
message: ChatMessage | SystemMessage | CustomMessage;
messageContainerStyle?: ComponentSlotStyle;
};
// @public (undocumented)
export type MessageStatus = 'delivered' | 'sending' | 'seen' | 'failed';
// @public
export const MessageThread: (props: MessageThreadProps) => JSX.Element;
// @public
export type MessageThreadProps = {
userId: string;
messages: (ChatMessage | SystemMessage | CustomMessage)[];
styles?: MessageThreadStylesProps;
disableJumpToNewMessageButton?: boolean;
disableReadReceipt?: boolean;
numberOfChatMessagesToReload?: number;
onMessageSeen?: (messageId: string) => Promise<void>;
onRenderReadReceipt?: (readReceiptProps: ReadReceiptProps) => JSX.Element | null;
onRenderAvatar?: (userId: string) => JSX.Element;
onRenderJumpToNewMessageButton?: (newMessageButtonProps: JumpToNewMessageButtonProps) => JSX.Element;
onLoadPreviousChatMessages?: (messagesToLoad: number) => Promise<boolean>;
onRenderMessage?: (messageProps: MessageProps, defaultOnRender?: DefaultMessageRendererType) => JSX.Element;
};
// @public (undocumented)
export interface MessageThreadStylesProps extends BaseCustomStylesProps {
chatContainer?: ComponentSlotStyle;
chatMessageContainer?: ComponentSlotStyle;
loadPreviousMessagesButtonContainer?: IStyle;
newMessageButtonContainer?: IStyle;
readReceiptContainer?: (mine: boolean) => IStyle;
systemMessageContainer?: ComponentSlotStyle;
}
// @public (undocumented)
export type MessageTypes = 'chat' | 'system' | 'custom';
// @public
export const MicrophoneButton: (props: MicrophoneButtonProps) => JSX.Element;
// @public
export interface MicrophoneButtonProps extends IButtonProps {
showLabel?: boolean;
}
// @public
export type NamedTheme = {
name: string;
theme: PartialTheme | Theme;
};
// @public
export const OptionsButton: (props: OptionsButtonProps) => JSX.Element;
// @public
export interface OptionsButtonProps extends IButtonProps {
showLabel?: boolean;
}
// @public
export const ParticipantItem: (props: ParticipantItemProps) => JSX.Element;
// @public
export interface ParticipantItemProps {
isYou?: boolean;
menuItems?: IContextualMenuItem[];
name: string;
onRenderAvatar?: (props?: ParticipantItemProps) => JSX.Element | null;
onRenderIcon?: (props?: ParticipantItemProps) => JSX.Element | null;
presence?: PersonaPresence;
styles?: ParticipantItemStylesProps;
}
// @public (undocumented)
export interface ParticipantItemStylesProps extends BaseCustomStylesProps {
avatar?: IStyle;
iconContainer?: IStyle;
isYou?: IStyle;
menu?: IStyle;
}
// @public (undocumented)
export interface PlaceholderProps {
avatarName?: string;
noVideoAvailableAriaLabel?: string;
}
// @public
export const ReadReceipt: (props: ReadReceiptProps) => JSX.Element;
// @public
export interface ReadReceiptProps {
deliveredTooltipText?: string;
failedToSendTooltipText?: string;
messageStatus?: MessageStatus;
seenTooltipText?: string;
sendingTooltipText?: string;
size?: SizeValue;
styles?: BaseCustomStylesProps;
}
// @public
export const recordButtonProps: IButtonProps;
// @public
export const ScreenShareButton: (props: ScreenShareButtonProps) => JSX.Element;
// @public
export interface ScreenShareButtonProps extends IButtonProps {
showLabel?: boolean;
}
// @public
export const SendBox: (props: SendBoxProps) => JSX.Element;
// @public
export interface SendBoxProps {
disabled?: boolean;
onMessageSend?: (content: string) => Promise<void>;
onRenderIcon?: (props: SendBoxProps, isMouseOverSendIcon: boolean) => JSX.Element | null;
onRenderSystemMessage?: (systemMessage: string | undefined) => React_2.ReactElement;
onTyping?: () => Promise<void>;
styles?: SendBoxStylesProps;
supportNewline?: boolean;
systemMessage?: string;
}
// @public (undocumented)
export interface SendBoxStylesProps extends BaseCustomStylesProps {
sendMessageIcon?: IStyle;
sendMessageIconContainer?: IStyle;
systemMessage?: IStyle;
textField?: IStyle;
}
// @public
export const StreamMedia: (props: StreamMediaProps) => JSX.Element;
// @public
export interface StreamMediaProps {
invertVideo?: boolean;
styles?: BaseCustomStylesProps;
videoStreamElement: HTMLElement | null;
}
// @public
export interface SwitchableFluentThemeContext {
currentTheme: NamedTheme;
setCurrentTheme: (namedTheme: NamedTheme) => void;
themeStore: ThemeCollection;
}
// @public
export const SwitchableFluentThemeProvider: (props: SwitchableFluentThemeProviderProps) => JSX.Element;
// @public
export interface SwitchableFluentThemeProviderProps {
children: React_2.ReactNode;
scopeId: string;
themes?: ThemeCollection;
}
// @public (undocumented)
export type SystemMessage = Message<'system'>;
// @public (undocumented)
export type SystemMessagePayload = {
messageId: string;
content?: string;
iconName?: string;
};
// @public
export type ThemeCollection = Record<string, NamedTheme>;
// @public
export const ThemeSelector: (props: ThemeSelectorProps) => JSX.Element;
// @public
export interface ThemeSelectorProps {
horizontal?: boolean;
label?: string;
}
// @public
export const ThemeToggler: (props: ThemeTogglerProps) => JSX.Element;
// @public
export interface ThemeTogglerProps {
label?: string;
layout?: string;
offTheme?: NamedTheme;
onTheme?: NamedTheme;
}
// @public
export const TypingIndicator: (props: TypingIndicatorProps) => JSX.Element;
// @public
export interface TypingIndicatorProps {
onRenderUsers?: (users: WebUiChatParticipant[]) => JSX.Element;
styles?: TypingIndicatorStylesProps;
typingString?: string;
typingUsers: WebUiChatParticipant[];
}
// @public (undocumented)
export interface TypingIndicatorStylesProps extends BaseCustomStylesProps {
typingString?: IStyle;
typingUserDisplayName?: IStyle;
}
// @public
export const useSwitchableFluentTheme: () => SwitchableFluentThemeContext;
// @public (undocumented)
export const VideoTile: (props: VideoTileProps & PlaceholderProps) => JSX.Element;
// @public
export interface VideoTileProps {
children?: React_2.ReactNode;
invertVideo?: boolean;
isVideoReady?: boolean;
placeholderProvider?: JSX.Element | null;
styles?: VideoTileStylesProps;
videoProvider?: JSX.Element | null;
}
// @public (undocumented)
export interface VideoTileStylesProps extends BaseCustomStylesProps {
overlayContainer?: IStyle;
videoContainer?: IStyle;
}
// @public
export type WebUiChatParticipant = {
userId: string;
displayName?: string;
};
// (No @packageDocumentation comment for this package)
```

Просмотреть файл

@ -0,0 +1,16 @@
// © Microsoft Corporation. All rights reserved.
import Package from './package.json';
import commonConfig from '../../common/config/rollup/rollup.config';
export default [
{
...commonConfig(Package),
input: './dist/dist-esm/communication-react/src/index.js',
output: {
file: './dist/dist-cjs/communication-react/index.js',
format: 'cjs',
sourcemap: true
}
}
];

Просмотреть файл

@ -0,0 +1,3 @@
// © Microsoft Corporation. All rights reserved.
export * from '../../react-components/src';

Просмотреть файл

@ -0,0 +1,9 @@
{
"extends": "../../common/config/tsc/tsconfig.json",
"compilerOptions": {
"outDir": "./dist/dist-esm"
},
"typeRoots": ["./node_modules/@types"],
"include": ["src/**/*"],
"exclude": ["dist", "node_modules"]
}

Просмотреть файл

@ -62,22 +62,6 @@ module.exports = {
env: {
jest: true
}
},
{
// remove the ban on certain types due to the complexity of this file
files: ['ConnectContext.tsx'],
rules: {
'@typescript-eslint/ban-types': 'off'
}
},
{
// remove ban on files affected by https://github.com/microsoft/rushstack/pull/1916.
// This should be removed once this issue is fixed
files: ['useFetchMessages.ts', 'ChatProviderHelper.tsx'],
rules: {
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-unused-vars': 'off'
}
}
]
};

Просмотреть файл

@ -11,7 +11,7 @@
"scripts": {
"build": "rushx build:esm && rushx build:cjs && api-extractor run --local",
"build:cjs": "rollup -c --silent --failAfterWarnings",
"build:esm": "tsc && copyfiles -u 1 src/**/assets/**/* dist/dist-esm",
"build:esm": "tsc",
"build:watch": "rushx build",
"test": "jest",
"test:coverage": "npm run test -- --coverage",
@ -27,7 +27,6 @@
"postpack": "node scripts/restore-pkg && copyfiles -E \"./*.tgz\" private-preview && copyfiles -u 2 -E \"docs/private-preview/README.md\" private-preview"
},
"dependencies": {
"@azure/acs-chat-selector": "~1.0.0-beta",
"@fluentui/react": "^7.117.1",
"@fluentui/react-icons": "^0.3.9",
"@fluentui/react-icons-northstar": "^0.51.2",

Просмотреть файл

@ -28,7 +28,7 @@ import {
SystemMessagePayload
} from '../types';
import { ReadReceipt, ReadReceiptProps } from './ReadReceipt';
import { memoizeFnAll } from '@azure/acs-chat-selector';
import { memoizeFnAll } from './utils/memoizeFnAll';
import { SystemMessage as SystemMessageComponent, SystemMessageIconTypes } from './SystemMessage';
const NEW_MESSAGES = 'New Messages';

Просмотреть файл

@ -0,0 +1,74 @@
// © Microsoft Corporation. All rights reserved.
export type FunctionWithKey<KeyT, ArgsT extends any[], RetT> = (key: KeyT, ...args: ArgsT) => RetT;
export type CallbackType<KeyT, ArgsT extends any[], FnRetT> = (
memoizedFn: FunctionWithKey<KeyT, ArgsT, FnRetT>
) => FnRetT[];
const argsCmp = (args1: any[], args2: any[], objCmp: (obj1: any, obj2: any) => boolean): boolean => {
return args1.length === args2.length && args1.every((arg1, index) => objCmp(args2[index], arg1));
};
/**
* The function memoize a series of function calls in a single pass,
* it memoizes all the args and return in a single run of the callback function, and read it in the next round of execution
* note: this is a memory opimized function which will only memoize one round of bulk calls
* @param fnToMemoize - the function needs to be bulk memorized, key paramter need to be provided as cache id
* @param shouldCacheUpdate - the validate function for comparing 2 argument, return true when 2 args are equal
* @returns callback function includes a series calls of memoizedFn, and each call will get cache result if args are the same(according to shouldCacheUpdate fn)
* @example
* ```ts
* const items = [{id:1, value:3}];
* const heavyFn = (_key, value) => { // key is not used in the function, but it is a cache id
* // assume this is a heavy caculation
* return value+1;
* }
*
* const memoizeHeavyFnAll = memoizeFnAll(heavyFn);
* const generateValueArray = (memoizedHeavyFn) => (
* items.map(item => {
* memoizedHeavyFn(item.id, item.value);
* })
* );
*
* const result = memoizeHeavyFnAll(generateValueArray); // Cache: {}, nextCache: {1: 4 *new}, heavyFn call times: 1
*
* // Argument changed
* items[0].value = 2
* const result0 = memoizeHeavyFnAll(generateValueArray); // Cache: {1: 4}, nextCache: {1: 3 *new}, heavyFn call times: 1
*
* // Cache added
* items.push({id:3, value:4});
* const result1 = memoizeHeavyFnAll(generateValueArray); // Cache: {1: 3 *hit}, nextCache: {1: 3, 3: 5 *new}, heavyFn call times: 1
*
* // Cache removed
* delete items[0];
* const result2 = memoizeHeavyFnAll(generateValueArray); // Cache: {1: 3, 3: 5 *hit}, nextCache: {3: 5}, heavyFn call times: 0
* ```
*/
export const memoizeFnAll = <KeyT, ArgsT extends any[], FnRetT, CallBackT extends CallbackType<KeyT, ArgsT, FnRetT>>(
fnToMemoize: FunctionWithKey<KeyT, ArgsT, FnRetT>,
shouldCacheUpdate: (args1: any, args2: any) => boolean = Object.is
): ((callback: CallBackT) => FnRetT[]) => {
let cache = new Map<KeyT, [ArgsT, FnRetT]>();
let nextCache = new Map<KeyT, [ArgsT, FnRetT]>();
return (callback: CallbackType<KeyT, ArgsT, FnRetT>): FnRetT[] => {
const memoizedFn: FunctionWithKey<KeyT, ArgsT, FnRetT> = (key: KeyT, ...args: ArgsT): FnRetT => {
const value = cache.get(key);
if (value) {
const [preArgs, ret] = value;
if (argsCmp(preArgs, args, shouldCacheUpdate)) {
nextCache.set(key, [args, ret]);
return ret;
}
}
const ret = fnToMemoize(key, ...args);
nextCache.set(key, [args, ret]);
return ret;
};
const retValue = callback(memoizedFn);
cache = nextCache;
nextCache = new Map<KeyT, [ArgsT, FnRetT]>();
return retValue;
};
};

Просмотреть файл

@ -1,30 +1,9 @@
{
"extends": "../../common/config/tsc/tsconfig.json",
"compilerOptions": {
"target": "es6",
"module": "esnext",
"jsx": "react",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist/dist-esm",
"strict": true,
"noImplicitAny": false, // disable for now for storybook
"strictFunctionTypes": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"esModuleInterop": true,
"typeRoots": ["./node_modules/@types"],
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleResolution": "node"
"outDir": "./dist/dist-esm"
},
"typeRoots": ["./node_modules/@types"],
"include": ["src/**/*"],
"exclude": ["dist", "node_modules"]
}

Просмотреть файл

@ -17,55 +17,60 @@
},
"telemetryEnabled": false,
"projects": [
{
"packageName": "@azure/communication-react",
"projectFolder": "packages/communication-react",
"reviewCategory": "production"
},
{
"packageName": "react-components",
"projectFolder": "packages/react-components",
"reviewCategory": "production"
"reviewCategory": "internal"
},
{
"packageName": "react-composites",
"projectFolder": "packages/react-composites",
"reviewCategory": "production"
"reviewCategory": "internal"
},
{
"packageName": "@azure/acs-chat-declarative",
"projectFolder": "packages/acs-chat-declarative",
"reviewCategory": "prototypes"
"reviewCategory": "internal"
},
{
"packageName": "@azure/acs-chat-selector",
"projectFolder": "packages/acs-chat-selector",
"reviewCategory": "prototypes"
"reviewCategory": "internal"
},
{
"packageName": "@azure/acs-calling-declarative",
"projectFolder": "packages/acs-calling-declarative",
"reviewCategory": "prototypes"
"reviewCategory": "internal"
},
{
"packageName": "@azure/acs-calling-selector",
"projectFolder": "packages/acs-calling-selector",
"reviewCategory": "prototypes"
"reviewCategory": "internal"
},
{
"packageName": "calling",
"projectFolder": "samples/Calling",
"reviewCategory": "prototypes"
"reviewCategory": "sample"
},
{
"packageName": "chat",
"projectFolder": "samples/Chat",
"reviewCategory": "prototypes"
"reviewCategory": "sample"
},
{
"packageName": "one-to-one-call",
"projectFolder": "samples/OneToOneCall",
"reviewCategory": "prototypes"
"reviewCategory": "sample"
},
{
"packageName": "server",
"projectFolder": "samples/Server",
"reviewCategory": "prototypes"
"reviewCategory": "sample"
},
{
"packageName": "storybook",